Getting to Know the Laravel Tinker Shell
Laravel Tutorials / updated: September 12, 2017

Getting to Know the Laravel Tinker Shell

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:

$ psysh
Psy Shell v0.8.11 (PHP 7.1.5 — cli) by Justin Hileman
>>> show array_key_exists
function 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:

$ psysh
Psy Shell v0.8.11 (PHP 7.1.5 — cli) by Justin Hileman
>>> doc array_key_exists
psysh
Psy Shell v0.8.11 (PHP 7.1.5 — cli) by Justin Hileman
>>> doc array_key_exists
function 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 request
function 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.

Laravel News Partners

Newsletter

Join the weekly newsletter and never miss out on new tips, tutorials, and more.