Tinker like a 10x: Mastering Artisan Tinker REPL for Laravel
Tags: webdev, laravel, programming, php
Published: 2023-05-01 11:33:35



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

```bash
>>> 10 + 11
=> 21
>>> $_ * 2
=> 42
>>> $_
=> 42

```

### Last exception

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


![Exception handling](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7euq7bdb5qa9nu8ndfrx.png)


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

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


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1uu3cawwyw1qrse9dq2y.png)



```php

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

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

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

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

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

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

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

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

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

```php
>>> hist --head 3 --save history.txt
Saving history in history.txt...
History saved.
>>>
```

### Clearing history

Clear your history with the `--clear` option.

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

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

```bash
>>> $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.

```php
>>> 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].   |   Aliases: ?|
 | ls              |  List local, instance or class variables, methods and constants.           |   Aliases: dir|
 | dump           |   Dump an object or primitive.||
 | doc           |    Read the documentation for an object, class, constant, method or property.  | Aliases: rtfm, man|
 | show          |    Show the code for an object, class, constant, method or property.||
 | wtf            |   Show the backtrace of the most recent exception.                         |    Aliases: last-exception, wtf?|
 | 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.             |          Aliases: buf|
 | 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.                                           |       Aliases: hist|
 | exit            |  End the current session and return to caller.                        |        Aliases: quit, q|
 | 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
<?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
<?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' => '>>> ',
    ],
];
```


![terminal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c07chjrwthjkuxo2sox2.png)


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!