DEV Community

Alpha Olomi
Alpha Olomi

Posted on

Tinker like a 10x: Mastering Artisan Tinker REPL for Laravel

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



Enter fullscreen mode Exit fullscreen mode

Last exception

The last uncaught error or exception is available as $_e.

Exception handling

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"



Enter fullscreen mode Exit fullscreen mode

Last file, line and directory

Some commands such as docdumpls, and show---set additional $__file$__line and $__dir variables, as appropriate.

Image description




>>> $__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"
>>>



Enter fullscreen mode Exit fullscreen mode

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
>>>


Enter fullscreen mode Exit fullscreen mode

⏳ 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
>>>


Enter fullscreen mode Exit fullscreen mode

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()
>>>



Enter fullscreen mode Exit fullscreen mode

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
>>>



Enter fullscreen mode Exit fullscreen mode

Searching history

Use the --grep option to filter your history.



>>> hist --grep wtf
4: wtf
>>>


Enter fullscreen mode Exit fullscreen mode

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()
>>>


Enter fullscreen mode Exit fullscreen mode

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(); }
>>>



Enter fullscreen mode Exit fullscreen mode

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
>>>



Enter fullscreen mode Exit fullscreen mode

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.
>>>


Enter fullscreen mode Exit fullscreen mode

Clearing history

Clear your history with the --clear option.



>>> hist --clear
History cleared.
>>> hist
>>>


Enter fullscreen mode Exit fullscreen mode

💲 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
  """
>>>



Enter fullscreen mode Exit fullscreen mode

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"
>>>


Enter fullscreen mode Exit fullscreen mode

✨ Shell commands with magic variables

Some commands such as docdumpls 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
>>>


Enter fullscreen mode Exit fullscreen mode

📢 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')),
];


Enter fullscreen mode Exit fullscreen mode

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' => '>>> ',
    ],
];


Enter fullscreen mode Exit fullscreen mode

terminal

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!

Top comments (3)

Collapse
 
alnahian2003 profile image
Al Nahian

Coooooooooool!

Collapse
 
alphaolomi profile image
Alpha Olomi

Thank you @alnahian2003

Collapse
 
giuliano1993 profile image
Giuliano1993

This is probably the most complete article about tinker I found until now! Thank you for the great job! 😃 🙏