Getting to Know the Laravel Tinker Shell
Published on by Paul Redmond
Laravel includes a powerful REPL, called Tinker, powered by the PsySH console by Justin Hileman under the hood. The tinker console allows you to interact with your Laravel application from the command line in an interactive shell.
Tinker used to be part of the laravel/framework
package, but with the release of Laravel 5.4 is extracted into separate package.
What is a REPL?
REPL stands for Read—Eval—Print—Loop, which is a type of interactive shell that takes in single user inputs, evaluates them, and returns the result to the user. I first learned about the concept of an interactive console through the rails console, which is part of the Ruby on Rails framework. Other languages, such as Ruby, come equipped with a REPL as a language feature. An interactive shell is a nice way to experiment with a language and framework.
PHP has an interactive shell you can use by running php -a
(pointed out by @lcjury), but PsySH has more features so I use it for a general interactive shell for PHP and tinker for Laravel applications.
Using PsySH Outside of Laravel
I highly recommend that you install the psysh package globally. You can install the psysh
command with composer by running the following:
composer global require psy/psysh:@stable
Make sure that your global composer bin/ is in your path so you can run psysh
from anywhere:
export PATH="~/.composer/vendor/bin:$PATH"
To start an interactive session, run the psysh
command. The following is an example of the built-in show
command which can show you the source code of a command:
$ psyshPsy Shell v0.8.11 (PHP 7.1.5 — cli) by Justin Hileman>>> show array_key_existsfunction array_key_exists($key, $search)Source code unavailable.
The help
command is your friend so that you can see the capabilities built-in to PsySH:
>>> help help ls dump doc show ...
I’ve removed the help command descriptions, but you get the idea.
You can even download the PHP core documentation as a CLI companion when you need to reference how a function works:
$ mkdir -p ~/.local/share/psysh/$ wget -O \ ~/.local/share/psysh/php_manual.sqlite http://psysh.org/manual/en/php_manual.sqlite
With the PHP Manual installed, you can read the documentation and then try it out in the CLI:
$ psyshPsy Shell v0.8.11 (PHP 7.1.5 — cli) by Justin Hileman>>> doc array_key_existspsyshPsy Shell v0.8.11 (PHP 7.1.5 — cli) by Justin Hileman>>> doc array_key_existsfunction array_key_exists($key, $search) Description: Checks if the given key or index exists in the array array_key_exists() returns TRUE if the given $key is set in the array. $key can be any value possible for an array index.... >>> array_key_exists('car', ['bike' => 'BMX']);=> false
I use PsySH all the time to verify how built-in PHP functions work and play around with PHP in an interactive way. Instead of using a REPL, I used to create an index.php file and run it with the PHP command to verify language features. Next time you do this, try using PsySH instead! The history
command alone is worth using a REPL so you can recall previous commands.
Laravel Tinker: PsySH on Steroids
Like I mentioned earlier, the “tinker” command sits on top of vanilla PsySH. Think of tinker as one of the best ways to experiment with your Laravel application. Let’s look at a few nice features that should supercharge your development workflow with Laravel.
Documentation Commands
The doc
command is a powerful way to look up documentation about a function or method. For example, let’s say you want to look up how the request()
helper function works:
$ php artisan tinker>>> doc requestfunction request($key = null, $default = null) Description: Get an instance of the current request or an input item from the request. Param: array|string $key mixed $default Return: \Illuminate\Http\Request|string|array
Or maybe I want to see the request()
code:
>>> show request > 633| function request($key = null, $default = null) 634| { 635| if (is_null($key)) { 636| return app('request'); 637| } 638| 639| if (is_array($key)) { 640| return app('request')->only($key); 641| } 642| 643| return data_get(app('request')->all(), $key, $default); 644| }
Artisan Commands in the Tinker Shell
When you run php artisan tinker
, the command starts up an interactive PsySH shell with Laravel bootstrapped. Before running the shell, the tinker
command adds commands to the shell. These commands get defined in the $commandWhitelist
property of the TinkerCommand class.
protected $commandWhitelist = [ 'clear-compiled', 'down', 'env', 'inspire', 'migrate', 'optimize', 'up',];
From this list, you can see that it’s possible to run up
and down
to toggle maintenance mode. You can also run migrate
to perform any pending migrations. Last, you can run clear-compiled
to clear the compiled class file.
Testing Laravel Code
Probably one of the most useful parts of Tinker, is the ability to play with Laravel code, such as models and services. You can use the console to create a new model for example:
$ php artisan tinker>>> use App\User;>>> $user = new User(['name' => 'John','email' => 'john@example.com']);$user->password = bcrypt('example');=> "$2y$10$2l1vIXYJy.Q5otmdaaNG5./l4jbxpYYlhrSipZAsJRwAuuzjsSXlq"$user->save();=> true$user->toArray();=> [ "name" => "John", "email" => "john@example.com", "updated_at" => "2017-09-12 06:37:13", "created_at" => "2017-09-12 06:37:13", "id" => 1, ]
Here’s my favorite database-related command in a Tinker session, the humble factory()
helper to create test users:
$ php artisan tinker>>> use App\User;>>> factory(User::class, 5)->create();...
Here’s how you could query the User model to get ten results back from the users
table:
$php artisan tinker>>> use App\User;>>> User::limit(10)->get();=> Illuminate\Database\Eloquent\Collection {#1071 all: [ App\User {#1072 id: 1, publisher_id: null, name: "John", email: "john@example.com", created_at: "2017-09-12 06:37:13", updated_at: "2017-09-12 06:37:13", }, ], }>>>
Tinker is a good place to trigger manual jobs and experiment with things like services, jobs, and events. For example, here we’re getting the log service from the container and writing to the log:
$ php artisan tinker>>> $log = app('log');=> Illuminate\Log\Writer {#1042}>>> $log->info('test');=> null
Learn More
The best way to find out more is to dive into a tinker session and use the help
command if you forget the commands you can run. The official psysh documentation is an excellent resource to get familiar with the underlying interactive shell. The interactive debugger capabilities and the wtf
command are some features you should check out. If you want to learn more about how tinker works, see the laravel/tinker package on GitHub.
Edit 09/12/2017: @lcjury pointed out that PHP does include an interactive shell by running php -a
from the command line.