December 7, 2016
The ability to easily interactive with your application to experiment or debug issues is an incredibly important thing. To help with this, Laravel provides a tinker
command out of the box. The tinker
command uses the PsySH library to setup a REPL (read-eval print loop) environment within the context of your Laravel application (this chapter may refer to Tinker, the Tinker REPL or Tinker environment; these are all referring to the same thing). The Tinker REPL allows you to interact with your application in a way that is not dissimilar to interacting with client-side code using products like Chrome's Developer Tools.
To get started using Tinker, simply issue the tinker
Artisan command in the root application directory:
1# Start a Tinker session.2php artisan tinker
If the Tinker session has started successfully, the console will display output similar to the following:
1Psy Shell v0.7.2 (PHP 7.0.8 — cli) by Justin Hileman2>>>
The Tinker REPL allows you to enter PHP code and have it evaluated immediately, similar to how Chrome's Developer Tools allow JavaScript developers to experiment directly with a running application. The following example demonstrates entering a PHP echo
statement; the results of the statement are displayed directly below the statement:
1Psy Shell v0.7.2 (PHP 7.0.8 — cli) by Justin Hileman2>>> echo 'Hello, from Tinker'3Hello, from Tinker4=> null5>>>
However, what makes Tinker a powerful and invaluable tool is the ability to interact with framework components and classes, as well as execute code in the context of a Laravel application. The following examples showcase using the Tinker REPL environment to create a new user (lines starting with >>>
are user input; lines starting with =>
are output):
1Psy Shell v0.7.2 (PHP 7.0.8 — cli) by Justin Hileman 2>>> $user = new App\User; 3=> App\User {#654} 4>>> $user->name = 'John Doe'; 5=> "John Doe" 6>>> $user->email = 'example@example.com'; 7=> "example@example.com" 8>>> $user->password = Hash::make('password'); 9=> "$2y$10$4FuGuqTEMSvoTRCObRCi4OUeBz9Me/7XR7mpNNKpFhtEXT8NuqwZm"10>>> $user;11=> App\User {#65412 name: "John Doe",13 email: "example@example.com",14 }15>>> $user->save();16=> true
In the previous example, the first thing that we did was create a new App\User
instance and assign it to the $user
variable. The $user
variable persists throughout the Tinker session; this is why we are able to set the properties on it before calling its save()
method. Every time we set a property value using Tinker, the assignment results will be displayed below. Similarly, each time a method is called the value returned by the method will be displayed.
The following example demonstrates retrieving a App\User
instance from the database using Tinker:
1Psy Shell v0.7.2 (PHP 7.0.8 — cli) by Justin Hileman 2>>> $user = App\User::find(1); 3=> App\User {#667 4 id: "1", 5 name: "John Doe", 6 email: "example@example.com", 7 created_at: "2016-08-03 23:37:14", 8 updated_at: "2016-08-03 23:37:14", 9 }10>>>
The JSON representation of the App\User
Eloquent model is displayed as the result of the find
method call. Remember that, by default, Eloquent models hide the password
and remember_me
fields when they are cast to JSON. However, these can easily be accessed directly from within a Tinker session:
1...23>>> $user->password;4=> "$2y$10$4FuGuqTEMSvoTRCObRCi4OUeBz9Me/7XR7mpNNKpFhtEXT8NuqwZm"5>>>
Tinker allows you to write any code expression, as long as it is valid; this also means ensuring that the namespaces are correct when referencing any classes. Interestingly, the REPL behind Tinker allows the use of the use
statement to import classes into scope. The following example session demonstrates this by importing the App\User
model and referencing it throughout the session:
1Psy Shell v0.7.2 (PHP 7.0.8 — cli) by Justin Hileman 2>>> use App\User; 3=> null 4>>> factory(User::class, 5)->create(); 5=> Illuminate\Database\Eloquent\Collection {#688 6 all: [ 7 App\User {#684 8 name: "Ethyl Ratke", 9 email: "erica33@example.com",10 updated_at: "2016-08-04 19:26:48",11 created_at: "2016-08-04 19:26:48",12 id: 27,13 },14 App\User {#68215 name: "Jordyn Goodwin Sr.",16 email: "nathen.bernier@example.com",17 updated_at: "2016-08-04 19:26:48",18 created_at: "2016-08-04 19:26:48",19 id: 28,20 },21 App\User {#68022 name: "Jameson Larkin",23 email: "lynn99@example.org",24 updated_at: "2016-08-04 19:26:48",25 created_at: "2016-08-04 19:26:48",26 id: 29,27 },28 App\User {#67929 name: "Dr. Ronny Fay DVM",30 email: "oberbrunner.corbin@example.net",31 updated_at: "2016-08-04 19:26:48",32 created_at: "2016-08-04 19:26:48",33 id: 30,34 },35 App\User {#68136 name: "Mr. Elbert Durgan",37 email: "cleta.jenkins@example.com",38 updated_at: "2016-08-04 19:26:48",39 created_at: "2016-08-04 19:26:48",40 id: 31,41 },42 ],43 }44>>> $user = User::find(30);45=> App\User {#69746 id: "30",47 name: "Dr. Ronny Fay DVM",48 email: "oberbrunner.corbin@example.net",49 created_at: "2016-08-04 19:26:48",50 updated_at: "2016-08-04 19:26:48",51 }52>>>
At times it is easier to enter arbitrary code that spans multiple lines. However, by default, pressing the Enter
key will cause the Tinker REPL to read and evaluate the line that was entered. To get around this, end the first line with the \
character. This allow you to continue the expression input on multiple lines; each line that will be part of the input will be prefixed with ...
. The REPL will continue to accept multi-line input until a valid terminator is encountered or a parsing error occurs.
If the current line contains the beginning of a PHP statement, such as an incomplete function declaration, the Tinker REPL will automatically switch to the multi-line expression mode.
The example session demonstrates this approach to supplying input to the Tinker REPL:
1>>> function sayHello($name) {2... return "Hello {$name}"; }3=> null4>>> sayHello("World")5=> "Hello World"
In the previous example, we did not have to supply the \
character. The following example session uses the \
character to force the REPL into multi-line input mode:
1>>> function sayHello($name) {} \2... function sayGoodBye($name) {}3=> null4>>>
Like the Artisan command-line application, Tinker provides many numerous commands and utilities that simplify the process of debugging and executing code from the command-line. The following table lists all the commands that Tinker provides (these commands can be discovered within the Tinker REPL by issuing the help
command):
Command | Description | Alias |
---|---|---|
help |
Show a list of commands. Type help [foo] for information about [foo]. |
? |
ls |
List local, instance or class variables, methods and constants. | list , dir |
dump |
Dump an object or primitive. | |
doc |
Read the documentation for an object, class, constant, method or property. | rtfm , man |
show |
Show the code for an object, class, constant, method or property. | |
wtf |
Show the backtrace of the most recent exception. | last-exception , wtf? |
whereami |
Show where you are in the code. | |
trace |
Show the current call stack. | |
throw-up |
Throw an exception out of the Psy Shell. | |
buffer |
Show (or clear) the contents of the code input buffer. | buf |
clear |
Clear the Psy Shell screen. | |
history |
Show the Psy Shell history. | hist |
exit |
End the current session and return to caller. | quit , q |
clear-compiled |
Remove the compiled class file. | |
down |
Put the application into maintenance mode. | |
env |
Display the current framework environment. | |
optimize |
Optimize the framework for better performance. | |
up |
Bring the application out of maintenance mode. | |
migrate |
Run the database migrations. | |
inspire |
Display an inspiring quote. |
Just like when interacting with most command-line utilities, each of the commands allow you to view help about any given command. To do this within Tinker, simply issue the help
command (or any of its aliases) followed by the name of the command you would like to learn more about.
The ordering of arguments is important when issuing commands within the Tinker REPL environment. For example, when using the Artisan command line application, retrieving help information is done by supplying the -h
argument after the command name; i.e., php artisan migrate -h
. Within the Tinker REPL environment, the help command is its own command and accepts the command to help with as its argument; i.e., ? buffer
.
The following example session shows the help information for the clear
command:
1>>> ? clear 2Usage: 3 clear 4 5Options: 6 --help (-h) Display this help message. 7 8Help: 9 Clear the Psy Shell screen.1011 Pro Tip: If your PHP has readline support, you should be able to use12 ctrl+l too!1314>>>
∎
The following amazing people help support this site and my open source projects ♥️
If you're interesting in supporting my work and want to show up on this list, check out my GitHub Sponsors Profile.