Tinker like a 10x: Mastering Artisan Tinker REPL for Laravel
Alpha Olomi
Posted on May 1, 2023
Introduction
As a Laravel developer, you probably spend a lot of time in the command line using Artisan commands to interact with your application. However, have you ever heard of Artisan Tinker? It's a powerful interactive REPL (Read-Eval-Print-Loop) tool that lets you interact with your Laravel application's code and data directly from the command line. In this article, we'll explore how to effectively use Artisan Tinker to supercharge your productivity and become a true 10x developer.
🖥 Getting started
To start using Artisan Tinker, simply run the php artisan tinker
command from your terminal. This will launch the Tinker REPL, which allows you to execute PHP code in the context of your Laravel application.
Here are some tips to help you get the most out of Tinker:
✨ Magic variables
Tinker provides several magic variables that you can use to reference different parts of your Laravel application.
Variable | Value |
---|---|
$_ |
Last result |
$_e |
Last exception |
$__out |
Last stdout output |
$__file |
Last file path |
$__line |
Last line |
$__dir |
Last directory path |
$__class |
Last class name |
$__method |
Last method name |
$__function |
Last function name |
$__namespace |
Last namespace name |
Last result
The result of the latest (successful) execution is always available as $_
, so you can use it in your next input.
>>> 10 + 11
=> 21
>>> $_ * 2
=> 42
>>> $_
=> 42
Last exception
The last uncaught error or exception is available as $_e
.
You can also use the wtf
command to view the latest exception's backtrace, and show --ex
to view the code which threw the exception.
To throw the most recent exception out of the current session, use the throw-up
command.
Last stdout
output
The stdout
output from the last code executed is captured, and is available as $__out
.
>>> echo "wat"
wat
>>> $__out
=> "wat"
Last file, line and directory
Some commands such as doc
, dump
, ls
, and show
---set additional $__file
, $__line
and $__dir
variables, as appropriate.
>>> $__file
= "/Users/alpha/Documents/GitHub/alphaolomi/opgs/vendor/psy/psysh/src/functions.php"
>>> $__line
= 29
>>> $__dir
= "/Users/alpha/Documents/GitHub/alphaolomi/opgs/vendor/psy/psysh/src"
>>>
Last namespace, class, method and function names
Some commands such as doc
and show
---set additional $__namespace
, $__class
, $__method
and $__function
variables, as appropriate.
>>> show Psy\Shell::debug
> 138| public static function debug(array $vars = array(), $boundObject = null)
139| {
140| echo PHP_EOL;
141|
142| $sh = new \Psy\Shell();
143| $sh->setScopeVariables($vars);
144|
145| if ($boundObject !== null) {
146| $sh->setBoundObject($boundObject);
147| }
148|
149| $sh->run();
150|
151| return $sh->getScopeVariables(false);
152| }
>>> $__namespace
=> "Psy"
>>> $__class
=> "Psy\Shell"
>>> $__method
=> "Psy\Shell::debug"
>>> $__function
PHP error: Undefined variable: __function on line 1
>>>
⏳ Managing history
Tinker also has a built-in history feature that allows you to easily recall previously executed commands. To access your command history, simply press the up and down arrow keys. The hist
command is your primary interface to history. With this command, you can show, search, save or replay your shell history.
Showing history
When invoked without options, the history
command shows all history. If there's a lot of it, the output will be paged.
>>> hist
0: function z() { throw new RuntimeException; }
1: function y() { z(); }
2: function x() { y(); }
3: x()
4: wtf
>>>
Show only a slice of history using the --show
option: --show 3
will show a single line, --show 1..3
will show a range, and --show 3..
will show from the third to the last line of your history.
>>> hist --show 1..3
1: function y() { z(); }
2: function x() { y(); }
3: x()
>>>
The --head N
and --tail M
options show the first N
lines and the last M
lines, respectively.
>>> hist --head 3
0: function z() { throw new RuntimeException; }
1: function y() { z(); }
2: function x() { y(); }
>>> hist --tail 2
3: x()
4: wtf
>>>
Searching history
Use the --grep
option to filter your history.
>>> hist --grep wtf
4: wtf
>>>
Use -i
to do a case-insensitive search, and -v
to show only lines which don't match the search pattern.
>>> hist --grep WTF -i -v
0: function z() { throw new RuntimeException; }
1: function y() { z(); }
2: function x() { y(); }
3: x()
>>>
The --grep
search pattern can be a Perl-compatible regular expression as well.
>>> hist --grep /\{.*\}/
0: function z() { throw new RuntimeException; }
1: function y() { z(); }
2: function x() { y(); }
>>>
Replaying history
Replay your history with the --replay
option. This works best when combined with --show
, --head
, --tail
and --grep
.
>>> hist --head 3 --replay
Replaying 3 lines of history
--> function z() { throw new RuntimeException; }
--> function y() { z(); }
--> function x() { y(); }
>>> function_exists('x')
=> true
>>>
Saving history
Save your history to a local file with the --save FILENAME
option. You can combine this with --show
, --head
, --tail
and --grep
options to limit the slice of history saved.
>>> hist --head 3 --save history.txt
Saving history in history.txt...
History saved.
>>>
Clearing history
Clear your history with the --clear
option.
>>> hist --clear
History cleared.
>>> hist
>>>
💲 System shell integration
Tinker can be integrated with your system shell to provide even more powerful functionality. It can be super useful to access a system shell from inside a REPL session.
Execute arbitrary shell commands
To execute arbitrary shell commands, wrap the command in backticks.
>>> `pwd`
=> "/Projects/psysh\n"
>>> `ls`
=> = """
README.md\n
app\n
artisan\n
bootstrap\n
composer.json\n
composer.lock\n
config\n
database\n
docs\n
history.txt\n
package.json\n
phpunit.xml\n
public\n
resources\n
routes\n
storage\n
tailwind.config.js\n
tests\n
vendor\n
vercel.json\n
vite.config.js\n
"""
>>>
PHP variables can be interpolated into shell commands as well.
>>> $readme = 'README.md'
=> "README.md"
>>> `ls -al $readme`
= "-rw-r--r-- 1 alpha staff 1441 May 1 12:34 README.md\n"
>>>
✨ Shell commands with magic variables
Some commands such as doc
, dump
, ls
and show
---update the $__file
, $__dir
and $__line
after they run. These variables are especially useful when interpolated into shell commands.
For example, after using doc
to show the documentation for a class or method, you can use the subl
shell command to open that file in Sublime Text and jump to the definition.
>>> doc Psy\Shell
class Psy\Shell extends Symfony\Component\Console\Application
Description:
The Psy Shell application.
Usage:
$shell = new Shell;
$shell->run();
Author: Justin Hileman <justin@justinhileman.info>
>>> $__file
=> "/Projects/psysh/src/Psy/Shell.php"
>>> `subl $__file:$__line`
=> null
>>>
📢 Commands
Tinker provides several built-in commands that you can use to perform common tasks. You see a full list of available commands by running help
.
Built-in commands
Command | Description | Aliases |
---|---|---|
help | Show a list of commands. Type help [foo] for information about [foo]. |
|
ls | List local, instance or class variables, methods and constants. | |
dump | Dump an object or primitive. | |
doc | Read the documentation for an object, class, constant, method or property. | |
show | Show the code for an object, class, constant, method or property. | |
wtf | Show the backtrace of the most recent exception. | |
whereami | Show where you are in the code. | |
throw-up | Throw an exception or error out of the Psy Shell. | |
timeit | Profiles with a timer. | |
trace | Show the current call stack. | |
buffer | Show (or clear) the contents of the code input buffer. | |
clear | Clear the Psy Shell screen. | |
edit | Open an external editor. Afterwards, get produced code in input buffer. | |
sudo | Evaluate PHP code, bypassing visibility restrictions. | |
history | Show the Psy Shell history. | |
exit | End the current session and return to caller. | |
migrate | Run the database migrations | |
migrate:install | Create the migration repository | |
inspire | Display an inspiring quote | |
clear-compiled | Remove the compiled class file | |
down | Put the application into maintenance / demo mode | |
env | Display the current framework environment | |
optimize | Cache the framework bootstrap files | |
up | Bring the application out of maintenance mode |
🛠 Configuration
Tinker's behavior can be customized using Laravel's configuration system.
To publish Tinker's configuration file, run php artisan vendor:publish --provider="Laravel\Tinker\TinkerServiceProvider"
. This will create a tinker.php
file in your application's config
directory.
🎛 Config options
Together with the tinker.php
config file, you can also directly pass options to the Psy\Shell
using config files.
Add a file to ~/.config/psysh/config.php
(or C:\Users\{USER}\AppData\Roaming\PsySH\config.php
on Windows).
<?php
return [
'startupMessage' => sprintf('<info>%s</info>', shell_exec('uptime')),
];
Per-project config files
For a per-project config create a .psysh.php
config file in the project root directory. Both the global and the local config files are used if they exist. The global config.php
is loaded first, and the local .psysh.php
overrides and extends the global configuration.
<?php
return [
'colorMode' => \Psy\Configuration::COLOR_MODE_FORCED,
'startupMessage' => sprintf('%s', shell_exec('php artisan about')),
'theme' => [
// Use compact output. This can also be set by the --compact flag.
'compact' => true,
// The standard input prompt.
'prompt' => '>>> ',
],
];
In our next article, we will dive into different recipes for using Tinker in your Laravel development. By demonstrating practical examples of how to use Tinker to debug, test, and interact with your application's code and data. Whether you are a beginner or an experienced developer, these recipes will help you improve your Tinker skills and become more efficient in your development process.
So, stay tuned for an upcoming article, and take your Laravel development skills to the next level with Artisan Tinker!
Posted on May 1, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.