Getting to Know the Laravel Tinker Shell

Published on by

Getting to Know the Laravel Tinker Shell image

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.

Paul Redmond photo

Staff writer at Laravel News. Full stack web developer and author.

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

Laravel Forge logo

Laravel Forge

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Forge
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
No Compromises logo

No Compromises

Joel and Aaron, the two seasoned devs from the No Compromises podcast, are now available to hire for your Laravel project. ⬧ Flat rate of $7500/mo. ⬧ No lengthy sales process. ⬧ No contracts. ⬧ 100% money back guarantee.

No Compromises
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $2500/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
LaraJobs logo

LaraJobs

The official Laravel job board

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit
Rector logo

Rector

Your partner for seamless Laravel upgrades, cutting costs, and accelerating innovation for successful companies

Rector
MongoDB logo

MongoDB

Enhance your PHP applications with the powerful integration of MongoDB and Laravel, empowering developers to build applications with ease and efficiency. Support transactional, search, analytics and mobile use cases while using the familiar Eloquent APIs. Discover how MongoDB's flexible, modern database can transform your Laravel applications.

MongoDB

The latest

View all →
Introducing Built with Laravel image

Introducing Built with Laravel

Read article
Visual EXPLAIN for MySQL and Laravel image

Visual EXPLAIN for MySQL and Laravel

Read article
VS Code Snippets for Livewire and Alpine.js image

VS Code Snippets for Livewire and Alpine.js

Read article
A guide to Laravel's model events image

A guide to Laravel's model events

Read article
API Versioning in Laravel 11 image

API Versioning in Laravel 11

Read article
A Resize Plugin for Alpine.js image

A Resize Plugin for Alpine.js

Read article