psy/psysh
PsySH is an interactive PHP REPL, runtime developer console, and debugger. Explore code, inspect variables, and run commands in a powerful shell with history, configuration, themes, and integrations—ideal for fast debugging and experimentation.
Installation:
composer require psy/psysh
For Laravel projects, PsySH is often pre-installed via laravel/tinker (which uses PsySH under the hood).
First Run:
vendor/bin/psysh
This launches an interactive REPL with access to your project’s autoloaded classes and functions.
First Use Case:
>>> $users = User::where('active', true)->get();
>>> $users->count()
=> 42
>>> $user = User::first();
>>> $user->posts
=> Collection {#324 ...}
$_ (last result), $_SERVER, $_ENV, etc.help or ? for built-in commands (e.g., ls, doc, edit).~/.psyshrc.php or .psysh.php in your project root for customizations.Debugging Logic:
>>> $total = 0;
>>> for ($i = 0; $i < 10; $i++) {
... $total += $i;
... }
>>> $total
=> 45
>>> try { User::find(999); } catch (\Exception $e) { $e }
=> Illuminate\Database\Eloquent\ModelNotFoundException {#324 ...}
Database Exploration:
>>> $query = User::query();
>>> $query->where('created_at', '>', now()->subDays(7));
>>> $query->get()->count()
=> 15
>>> DB::select('SELECT * FROM users LIMIT 5');
=> array:5 [ ... ]
Testing APIs/Endpoints:
Http::get() or Http::post() to test API responses:
>>> $response = Http::get('https://api.example.com/users');
>>> $response->json()
=> ["data"=>[ ... ]]
Configuration Inspection:
.env values:
>>> config('app.debug')
=> true
>>> env('APP_URL')
=> "https://example.com"
Artisan Commands:
>>> Artisan::call('migrate:status');
>>> Artisan::output()
=> "Migrations status: ..."
Laravel-Specific:
use App\Models\User; to auto-load models (or rely on Laravel’s autoloader).>>> app('db')->connection()->getPdo();
>>> event(new \App\Events\UserRegistered($user));
Custom Helpers:
.psysh.php:
// .psysh.php
function dd(...$args) {
\Psy\Output\Output::dumpAndDie(...$args);
}
History Management:
history to browse past commands.save and reload with load.Multi-Line Editing:
Enter mid-statement to continue on the next line (with proper indentation).Ctrl+D to exit multi-line input.Security:
.psysh.php) and autoloads. If you see warnings about untrusted projects:
--trust-project flag or set 'trustProject' => 'always' in config.Autoloading:
autoload.php is loaded (check psy\info()).psr-4 namespace or manually included.composer dump-autoload if classes are missing.Output Quirks:
; suppress output (like MATLAB). Use ;; if 'semicolonsSuppressReturn' => 'double' is set.<<<EOD ... EOD) for cleaner output. Avoid """ for consistency.Experimental Features:
--experimental-readline or 'useExperimentalReadline' => true. Opt-in due to potential bugs.'useSyntaxHighlighting' => false if it’s distracting.Performance:
uopz extension. Not all code can be reloaded (e.g., class properties). Use yolo to bypass safety checks.User::all()) may bloat the REPL. Use unset($var) to free memory.Inspecting Variables:
var_dump() or print_r() for raw output:
>>> var_dump($user);
Psy\Output\Output::dump() for colored, formatted output.Command Not Found:
\ to force PHP execution (e.g., \config instead of config).psy\info() for loaded commands.Terminal Issues:
Ctrl+C to interrupt. If it doesn’t work, try Ctrl+\ or restart the shell.--no-pager if output is truncated.Configuration Overrides:
config pager false) persist only for the current session.~/.psyshrc.php or .psysh.php.Custom Commands:
Psy\Command\CommandInterface and register it in .psysh.php:
$commands[] = new class implements \Psy\Command\CommandInterface {
public function getName() { return 'mycmd'; }
public function getDescription() { return 'My custom command'; }
public function handle(\Psy\Shell $shell) {
echo "Hello from mycmd!\n";
}
};
Themes:
.psysh.php:
'theme' => [
'prompt' => '<fg=blue>psysh</> <fg=green>%s</>',
'keywords' => ['<fg=yellow>'],
'strings' => ['<fg=magenta>'],
];
Clipboard Integration:
copy:
'clipboardCommand' => 'pbcopy', // macOS
'clipboardCommand' => 'xclip -selection clipboard', // Linux
Exception Details:
exceptionDetails:
'exceptionDetails' => function (\Throwable $e) {
return "File: {$e->getFile()}:{$e->getLine()}\n" . $e->getTraceAsString();
};
Hot Reloading:
yolo:
'hotReload' => [
'whitelist' => [__DIR__ . '/app/Helpers/*.php'],
];
How can I help you explore Laravel packages today?