A runtime developer console, interactive debugger and REPL for PHP.

Watch on GitHub Fork on GitHub Share on Google+

Have eight seconds? Try PsySH

The easy way

~ $ wget

~ $ chmod +x psysh

~ $ ./psysh


The other easy way

~ $ composer g require psy/psysh:@stable

~ $ psysh

Stop die()ing all the time

PsySH can be used as an interactive debugger, much like JavaScript's debugger statement, saving you from endless var_dump() and die() iterations. Just drop this line in where you'd like to have a breakpoint:


Name <em>all</em> the spaces

Name all the spaces

Most PHP shells are terrible at namespaces. PsySH does just what you'd expect.

Read documentation in context

Have a question about a core PHP function? Try doc array_map. Want to read the documentation for an object property? Run doc $response->statusTexts.

>>> help doc

Read documentation in context
Reflect like a boss

Reflect like a boss

The list command knows all about your code — and everyone else's. Easily list and search all variables, constants, classes, interfaces, traits, functions, methods and properties.

>>> help list

Use the source!

Easily show the source code for any userland object, class, interface, trait, constant, method or property.

>>> help show

Use the source!
Forget to catch that last exception?

Forget to catch that last exception?

No worries, PsySH has your back. We caught it for you, and made it available via the wtf command.

>>> help wtf

Learn from your history and repeat your past

Show, search, save and replay your shell history.

>>> help history

Learn from your history <em>and</em> repeat your past

Roll your own commands

If the awesome features listed above aren't enough for you, you can write your own commands! PsySH has first-class support for custom commands — just register them in your ~/.psysh/rc.php.

How is this thing better than

Check out the slides from Interactive Debugging in PHP at OSCON 2013 for an overview of the state of PHP debugging and why PsySH might be for you.


PsySH as a REPL

PsySH functions as a REPL for PHP right out of the box! Once you've installed PsySH, running it directly (psysh or ./psysh) will drop you into an interactive prompt, like so:

~ $ ./psysh
Psy Shell v0.1.0-dev (PHP 5.4.9-4ubuntu2.2 — cli) by Justin Hileman

From here, you can type PHP code and see the result interactively:

>>> function timesFive($x) {
...     $result = $x * 5;
...     return $result;
... }
=> null
>>> timesFive(10);
=> 50

PsySH as a Debugger

To use PsySH as a debugger, install it as a Composer dependency or include the Phar directly in your project:


Then, drop this line into your script where you'd like to have a breakpoint:


… which is just a shorter way of saying:


When your script reaches this point, execution will be suspended and you'll be dropped into a PsySH shell. Your program state is loaded and available for you to inspect and experiment with.

Pro Tip™: You don't have to use get_defined_vars… You can pass anything you want in as your debugging context:

$result = \Psy\Shell::debug(['app' => $myApp]);

If you're starting the debug shell from inside a class context, you can pass an optional second argument to add a bound object to the shell. This is super useful because you'll be able to call things on $this inside your debug shell, and you will have full access to private and protected members of your current context:

\Psy\Shell::debug(get_defined_vars(), $this);

If you call the shortcut eval(\Psy\sh()) from inside a class context, you'll get $this bound for free.

Magic Variables

The result of the last (successful) statement is available as $_, and the last error or exception is available as $_e. You can use these just like you'd use any other variable:

>>> 'wat'
=> "wat"
>>> $_
=> "wat"
>>> throw new Exception($_)
Exception with message 'wat'
>>> $_e
=> <Exception #000000004db607ea000000017892abf1> {
       message: "wat",
       file: "phar:///usr/local/bin/psysh/src/Psy/ExecutionLoop/Loop.php(67) : eval()'d code",
       line: 1


While PsySH strives to detect the right settings automatically, you might want to configure it yourself. Just add a file to ~/.psysh/rc.php:


return array(

    // In PHP 5.4+, PsySH will default to your `cli.pager` ini setting. If this
    // is not set, it falls back to `less`. It is recommended that you set up
    // `cli.pager` in your `php.ini` with your preferred output pager.
    // If you are running PHP 5.3, or if you want to use a different pager only
    // for Psy shell sessions, you can override it here.
    'pager' => 'more',

    // By default, PsySH will use a 'forking' execution loop if pcntl is
    // installed. This is by far the best way to use it, but you can override
    // the default by explicitly enabling or disabling this functionality here.
    'usePcntl' => false,

    // PsySH uses readline if you have it installed, because interactive input
    // is pretty awful without it. But you can explicitly disable it if you
    // hate yourself or something.
    'useReadline' => false,

    // "Default includes" will be included once at the beginning of every PsySH
    // session. This is a good place to add autoloaders for your favorite
    // libraries.
    'defaultIncludes' => array(

    // While PsySH ships with a bunch of great commands, it's possible to add
    // your own for even more awesome. Any Psy command added here will be
    // available in your Psy shell sessions.
    'commands' => array(

        // The `parse` command is a command used in the development of PsySH.
        // Given a string of PHP code, it pretty-prints the
        // [PHP Parser]( parse tree. It
        // prolly won't be super useful for most of you, but it's there if you
        // want to play :)
        new \Psy\Command\ParseCommand,

    // PsySH ships with presenters for scalars, resources, arrays, and objects.
    // But you're not limited to those presenters. You can enable additional
    // presenters (like the included MongoCursorPresenter), or write your own!
    'presenters' => array(
        new \Psy\Presenter\MongoCursorPresenter,

    // You can disable tab completion if you want to. Not sure why you'd want to.
    'tabCompletion' => false,

    // You can write your own tab completion matchers, too! Here are some that enable
    // tab completion for MongoDB database and collection names:
    'tabCompletionMatchers' => array(
        new \Psy\TabCompletion\Matcher\MongoClientMatcher,
        new \Psy\TabCompletion\Matcher\MongoDatabaseMatcher,