PHPackages                             alexpw/boris - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. alexpw/boris

ActiveLibrary[CLI &amp; Console](/categories/cli)

alexpw/boris
============

1.0.13(11y ago)4861PHPPHP &gt;=5.3.0

Since Apr 23Pushed 10y ago1 watchersCompare

[ Source](https://github.com/alexpw/boris)[ Packagist](https://packagist.org/packages/alexpw/boris)[ RSS](/packages/alexpw-boris/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (4)Versions (20)Used By (0)

Boris
=====

[](#boris)

This is a fork, please see and consider [the original](https://github.com/d11wtq/boris). This fork is fully functional, but is not battle tested. The rest of this README has been modified to accurately reflect this fork.

Differences from Original
-------------------------

[](#differences-from-original)

- Redefine existing functions and (basic) classes to quickly experiment with code.
- Available when runkit ext is installed (optional).
- Swapped PHP's readline for a custom one based on [Hoa Console](hoa-project.net/En/Literature/Hack/Console.html)
    - This provided full control over the UX, but a lot of potential bugs reinventing the basics.
- Autocomplete, thanks to [joddie](https://github.com/joddie/boris/tree/completion-and-network-hacks)!
- Backported to support php 5.3
- "Macro" support, allows transforming the input before it is evaled.
    - Support for PHP's "use" statements, just a macro.
- Multi-line history.

Intro
-----

[](#intro)

A REPL for PHP.

> **Announcement:** I'm looking to add one or two additional collaborators with commit access. If you are actively involved in open source and have a GitHub profile for review, ping me on Twitter (@d11wtq) to express your interest. Experienced developers with active GitHub projects only.

[![Demo](https://camo.githubusercontent.com/c0562c06d622822b0567bf9ef901e40293baa05311144baa67078e9e24d98131/687474703a2f2f646c2e64726f70626f782e636f6d2f752f3530383630372f426f72697344656d6f2d76342e676966 "Quick Demo")](https://camo.githubusercontent.com/c0562c06d622822b0567bf9ef901e40293baa05311144baa67078e9e24d98131/687474703a2f2f646c2e64726f70626f782e636f6d2f752f3530383630372f426f72697344656d6f2d76342e676966)

Python has one. Ruby has one. Clojure has one. Now PHP has one too. Boris is PHP's missing REPL (read-eval-print loop), allowing developers to experiment with PHP code in the terminal in an interactive manner. If you make a mistake, it doesn't matter, Boris will report the error and keep on going.

Everything you enter into Boris is evaluated and the result inspected so you can understand what is happening. State is maintained between inputs, allowing you to gradually build up a solution to a problem.

Why?
----

[](#why)

I have come to find PHP's lack of a real REPL to be frustrating and was not able to find an existing implementation that was complete.

Facebook's [phpsh](http://phpsh.org/) is written in Python, abandoned, and most of the feature list doesn't work for me in the latest commits.

Ieure's [PHP\_Repl](https://github.com/ieure/php_repl) is 5 years old. It's got some great stuff, but terminates on fatals, a deal breaker.

Installation
------------

[](#installation)

### 1. Via packagist

[](#1-via-packagist)

For use with composer.

-

### 2. Directly from this repo

[](#2-directly-from-this-repo)

This is great if you want to stay really up-to-date, but I (alexpw) may commit unstable code to master, at least until someone else starts using this fork.

```
git clone git://github.com/alexpw/boris.git
cd boris
./bin/boris

```

### 3. Build your own phar

[](#3-build-your-own-phar)

You can also build a PHAR file using [Box](http://box-project.org/):

```
box build

```

This will create a `boris.phar` file. Feel free to move it into your bin directory:

```
chmod +x boris.phar
mv boris.phar /usr/local/bin/boris

```

### Pro Tip

[](#pro-tip)

Add boris to your $PATH for easy access.

Usage
-----

[](#usage)

When Boris starts, you will be at the `php>` prompt. PHP code you enter at this prompt is evaluated. If an expression spans multiple lines, Boris will collect the input and then evaluate the expression when it is complete. Press CTRL-C to clear a multi-line input buffer if you make a mistake.

```
php> $x = 1;
// 1
php> $y = 2;
// 2
php> "x + y = " . ($x + $y);
// "x + y = 3"
php> exit

```

You can also use CTRL-D to exit the REPL.

### Cancelling long-running operations

[](#cancelling-long-running-operations)

Long-running operations, such as infinite loops, may be cancelled at any time without quitting the REPL, by using CTRL-C while the operation is running.

```
php> for ($i = 0; ; ++$i) {
  *>   if ($i % 2 == 0) printf("Tick\n");
  *>   else             printf("Tock\n");
  *>   sleep(1);
  *> }
Tick
Tock
Tick
Tock
Tick
Tock
Tick
^CCancelling...
php>

```

### Using Boris with your application loaded

[](#using-boris-with-your-application-loaded)

You can also use Boris as part of a larger project (e.g. with your application environment loaded).

```
require_once 'lib/autoload.php';

$boris = new \Boris\Boris('myapp> ');
$boris->start();

```

The constructor parameter is optional and changes the prompt.

If you want to pass local variables straight into Boris (e.g. parts of your application), you can do that too (thanks to [@dhotston](https://github.com/dhotston)):

```
$boris = new \Boris\Boris('myapp> ');
$boris->setLocal(array('appContext' => $appContext));
$boris->start();

```

In the above example, $appContext will be present inside the REPL.

### Using start hooks

[](#using-start-hooks)

It is possible to add callbacks to Boris that are executed inside the REPL before it begins looping. Any number of hooks can be added, and they will be executed in order. Any variables set or exported by the hook will become visible from inside the REPL and consequently, to subsequent hooks that are run.

There are two ways to specify hooks: as arbitrary strings of PHP code to evaluate, or as callbacks given as closures. Both approaches allow you access to the scope, though you need to do slightly more work with the callback approach.

```
// this will simply be evaluated in the REPL scope
// the variables $foo and $bar will be visible inside the REPL
$boris->onStart('$foo = 42; $bar = 2; echo "Hello Boris!\n";');

// this will be passed the REPL and it's scope as arguments
// any changes to the scope can be expressed by invoking the usual
// methods on the REPL
$boris->onStart(function($worker, $scope){
  extract($scope); // we could also just access specific vars by key

  echo '$foo * $bar = ' . ($foo * $bar) . "\n";

  $worker->setLocal('name', 'Chris');
});

```

Above we added two hooks. The first just gets passed to `eval()` and leaves `$foo` and `$bar` in scope. The second uses the callback style and reads its variables from the `$scope` parameter, then sets variables into the REPL with `setLocal()`.

### User configuration files

[](#user-configuration-files)

If you have, things you always want to do when Boris starts, such as load useful utility functions, change the prompt or set local variable, you may create a ~/.borisrc.php file, which will be loaded whenever Boris starts up (also supports ~/.borisrc, but you'll lose syntax highlighting).

The contents of this file are just arbitrary PHP code. You are *not* inside the REPL itself in this file, but you have access to `$boris`, which is the REPL object. Here's an example ~/.borisrc.php that sets the prompt.

```
