PHP
Article

How to Use PHPbrew and VirtPHP

By Phil Sturgeon

We’ve all been in the situation where we have one version installed. Maybe that version is whatever came installed on our operating system. Maybe it is a version bundled into MAMP/WAMP/XAMPP.

How do you go about switching that PHP version?

How do you switch to one version, then switch back again?

How do you go about switching that version of PHP, but only for one single application on your computer?

The Ruby and Python communities have had tools for dealing with this for years. PHP has them now too, but there was nowhere near enough fanfare.

PHPbrew

PHPbrew is an amazing little tool which has been out since 2012.

It builds and installs PHP versions, and places them into a folder in your home directory. This means you can manage your own versions of PHP. PHPbrew will build various versions, place them in the home folder, and let you switch between them whenever you want.

Installing PHPbrew

It should be worth noting that PHPbrew has a fair few requirements, but they are not tough to install. I did not have to install anything, as after using this Macbook for over two years I had all the requirements anyway.

If you are a Mac OS X user – and I will continue to assume that you are – then you can use Homebrew (no relation) to install dependencies.

brew install automake autoconf curl pcre re2c mhash libtool icu4c gettext jpeg libxml2 mcrypt gmp libevent
brew link icu4c

Then you will need to install PHPbrew itself:

curl -L -O https://github.com/phpbrew/phpbrew/raw/master/phpbrew
chmod +x phpbrew
sudo mv phpbrew /usr/bin/phpbrew

This downloads PHPbrew, adds the “executable” permission and moves it to /usr/bin directory.

Hop over to their basic usage instructions to see how to get things initialized in more detail, but the basics should just be:

phpbrew init

With phpbrew initialised you will need to add these lines to your .bashrc:

echo "source $HOME/.phpbrew/bashrc" >> ~/.bashrc

If you are using a non-default shell like ZSH then you will need to edit your .zshrc file instead.

Installing PHP using PHPbrew

Before we can install a version of PHP, we need to see which versions are available to PHPbrew. We can do this with a simple command:

phpbrew known
Available stable versions:
5.6+	5.6.0
5.5+		5.5.17, 5.5.16, 5.5.15, 5.5.14, 5.5.13, 5.5.12, 5.5.11, 5.5.10
5.4+	5.4.33, 5.4.32, 5.4.31, 5.4.30, 5.4.29, 5.4.28, 5.4.27, 5.4.26
5.3+		5.3.29, 5.3.28, 5.3.27, 5.3.26, 5.3.25, 5.3.24, 5.3.23, 5.3.22

At the time of writing, PHP 5.6.0 is the latest version, and versions of PHP before 5.3 are not supported.

We want to install PHP 5.6.0, so we can use all the great new features, so lets ask phpbrew to do that:

phpbrew install 5.6.0

Note that if you are using PHPbrew 1.14 or earlier then this would fail on some systems with an error about not having XML enabled. When XML is missing, PHPbrew will fail to install something called PEAR and the build will break. We can get around that using the +xml_all option:

phpbrew install 5.6.0 +xml_all

This +xml_all option is what PHPbrew calls “Variants”, and there are a lot more available.

Variants

When installing PHP yourself, there are lots of options to enable or disable features. PHPbrew simplifies this and abstracts it, using a feature called Variants.

Things like database drivers, curl, the GD image library and JSON are all available as optional variants.

PHPbrew has one variant called “default”, which – contrary to expectation – is not used by default. Instead it acts as a shortcut for enabling the following variants:

  • bcmath
  • bz2
  • calendar
  • cli
  • ctype
  • dom
  • fileinfo
  • filter
  • ipc
  • json
  • mbregex
  • mbstring
  • mhash
  • pcntl
  • pdo
  • posix
  • readline,
  • sockets
  • xml_all
  • zip

The default may contain more than you need, so a more granular approach may be more to your liking.

Lets say we just want to install PHP 5.6.0 to build a CLI application, that uses PDO to talk to a SQLite database. For that, we can do the following:

phpbrew install 5.6.0 +cli +pdo +sqlite +xml_all

This command will enable the PDO extension itself, and sqlite enables the SQLite drivers. The cli variant will install the command-line interface, and xml_all will stop PHPbrew complaining about PEAR.

If you have any trouble installing a version of PHP, try running the same command but add the -d option. This will send debug information to the console, instead of sending it to a log file.

phpbrew install -d 5.6.0 +default +sqlite

Switching PHP versions

So, at this point we should have a version of PHP installed.

If our installation was a success then PHPbrew will output a message like this:

Congratulations! Now you have PHP with php-5.6.0.
To use the newly built PHP, try the line(s) below:

    $ phpbrew use php-5.6.0

Or you can use switch command to switch your default php version to php-5.6.0:

    $ phpbrew switch php-5.6.0

The first command listed use will let you use PHP 5.6.0 while you’re in that console session. If you close the tab/window or restart your computer then you’ll be back to whichever version of PHP is the default.

The second command switch will switch the default version of PHP that PHPbrew will go to on a new session.

Lets try setting the default version to be PHP 5.6.0, and see if it works.

$ phpbrew switch php-5.6.0
$ php -v
PHP 5.6.0 (cli) (built: Sep 30 2014 15:30:22) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies

The output above shows us exactly what we want to see: PHP 5.6.0.

If we now try installing the older PHP 5.5, we can once again use $ phpbrew known to see which versions are available. Pick a version, and try to install it:

phpbrew install 5.5.17 +default +sqlite

This will install PHP 5.5.17 with the default and sqlite variants. To then use PHP 5.5.17, we have to run another command:

$ phpbrew use php-5.5.17
$ php -v
PHP 5.5.17 (cli) (built: Sep 30 2014 17:41:05) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies

Now we can use PHP 5.5.17 in this session, and use PHP 5.6.0 again. As we used the use command not switch, when we open another tab or window, PHP 5.6.0 will once again be there.

PHPbrew vrs. System

When we are using a PHPbrew version of PHP, our bash session will be using a special path for the PHP version. We can find out which version is in use with the which command:

$ which php 
/Users/phil/.phpbrew/php/php-5.6.0/bin/php

If we would like to stop using this phpbrew version of PHP and go back to the system version, we can use the off command.

$  phpbrew off
phpbrew is turned off.
$ which php
/usr/bin/php
$ php -v
PHP 5.4.24 (cli) (built: Jan 19 2014 21:32:15) 
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies

Once again we’re using the default version. You may not need this, but it is handy to know how to get rid of phpbrew. The which command will also help you out with debugging.

PHPbrew by itself is a useful tool, and you might find this is all you need. That said, these versions of PHP can get complicated when you find that various projects need more extensions. PHPBrew can add PECL extensions, but not a project-by-project basis.

It also assumes you can remember which version of PHP an application should be using. It might not be the default, and running it under another version could cause problems.

To do this, we need to look at using another tool on top of PHPbrew.

VirtPHP

VirtPHP lets you make isolated PHP environments on a single machine, like Python’s virtualenv. That might sound a little complicated but the idea is simple.

To start, you mark one directory which contains an application or component, and give it a name. Imagine we were working on “airpair-api” and its a PHP app, we’d want to make that its own environment.

Then, we could install PECL extensions that “airpair-api” needs, without affecting other applications.

That’s the theory, so let’s take a look at how we do that.

Installing virtPHP

Go to the virtPHP releases page and find the latest release. It will have a link saying “virtphp.phar”, and you’ll want to right click and copy that URL.

$ wget https://github.com/virtphp/virtphp/releases/download/v0.5.1-alpha/virtphp.phar
chmod +x virtphp.phar
sudo mv virtphp.phar /usr/bin/virtphp

Now we can check to see if it is working:

$ virtphp -V
virtPHP version v0.5.1-alpha 2014-08-13 16:05:47

Creating Environments

VirtPHP maintains a relaxed approach to which version of PHP is in use. When you go to create an environment, it will take whichever version of PHP you have in your console session and reference that.

So, before we try to make a new environment, we need to be certain we are using the right version.

$ which php           
/Users/phil/.phpbrew/php/php-5.6.0/bin/php

Oops, it’s still using the default version and I want to make sure my codebase is working on PHP 5.5.

$ phpbrew use 5.5.17
$ which php           
/Users/phil/.phpbrew/php/php-5.5.17/bin/php

Perfect, the currently enabled version of PHP is 5.5.17, which in this example is the one we want.

Now we can make an environment.

virtphp create airpair-api

You will see a lot of output, and if goes well then you should see the following:

Your virtual php environment (airpair-api) has been created!
You can activate your new environment using: ~$ source /Users/phil/.virtphp/envs/airpair-api/bin/activate

At this point the new environment is ready to use, but not enabled. Copy the command it gives you and run it, or run this shorter version:

$ source ~/.virtphp/envs/airpair-api/bin/activate

Now you should see the name of the environment (airpair-api) in the console prompt, before the $ character. This lets you know that you are in an environment, so you can deactivate it or act accordingly.

Playing in the Sandbox

Now we have this environment, we can install and configure things without affecting other PHP installations.

One great use-case for using environments is being able to install PECL extensions. Not only can you test how an app works with or without the extension, but you can try different versions too.

(airpair-api) $ pecl install xdebug
(airpair-api) $ pecl install memcached-1.0.2

This helps us install the great debugging tool Xdebug, and install the [memcached] extension.

At the time of writing, the PECL command installs packages via the PEAR-based system. In future versions of virtPHP, PECL extensions will install via the new and improved Pickle system. This will remove a few issues that OS X seems to have with supporting PEAR.

Exiting an Environment

To check if you’re still using an environment, two things will help. The first clue is to see the environment name in brackets in your command prompt. The second is to use which php and see if its pointing to a virtPHP environment.

(airpair-api) $ which php
/Users/phil/.virtphp/envs/airpair-api/bin/php
(airpair-api) $ deactivate
$ which php
/Users/phil/.phpbrew/php/php-5.6.0/bin/php

There you can see we were using the airpair-api environment. Then after deactivating it, the console fell back to using 5.6.0 installed from PHPbrew, as that is default.

Conclusion

Playing with many installed versions like this can at first seem a little confusing. In reality, there is much less to learn here than trying to teach a beginner developer all about a full stack.

If a new developer was to try and build a basic PHP app, traditionally they would go through the following steps to get started:

  • Apache/nginx
  • MySQL
  • Virtual Hosts and /etc/hosts
  • Hack the core OS PHP version
  • Maybe install XAMPP/WAMP/MAMP instead
  • Try to upgrade the core versions or *AMP versions
  • Get confused that system PHP and MAMP PHP is different
  • Try to install PECL extensions to MAMP version, but install them to system PHP instead

You can avoid a lot of that pain with a tool like Vagrant and a provision script, but that assumes that this beginner is in a team. If going solo, the beginner would have a much harder time getting started.

This is how the Ruby on Rails community has done things for years. Teach beginners a framework, abstract away a lot of the hard stuff, get them building and let them learn more about it all as they grow.

Grab your PHP version, install what you need, run the PHP development server with php -S and only beef up your stack when (or if) you need to.

Dev/Prod parity is important, but sometimes you can get away with not caring too much if its just a simple little HTTP service. If you already have CI testing in place then this is even more true.

Finaly, even if you don’t want to run the code through the development server, having PHPbrew and virtPHP are still useful. You can install new versions as soon as they come out to play with the new syntax, and not break all your apps.

  • WooDzu

    That deserves a WOW! I’ll definitely give this a go next time I need to setup dev vm. Nice read

  • ejunker

    Maybe I missed it, but does this work if you are using apache and mod_php?

    • http://www.bitfalls.com/ Bruno Skvorc

      VirtPHP still has no support for Apache, but it’s planned.

  • http://w3guy.com Agbonghama Collins

    Welcome Phil to Sitepoint.

    • philsturgeon

      Thanks!

  • Miloslav Nenadál

    Interesting. Currently, I am using phpfarm https://github.com/fpoirotte/phpfarm for linux (for versions without the server I am using php-cgi with apache so I just set different paths for different virtualhosts).

  • Ajepe Babatope De Immaculate

    This seem a little confusing.

    • philsturgeon

      How can I help clear it up for you?

  • hot_rush

    phpbrew is very buggy

    • philsturgeon

      All software has bugs. I didn’t notice any bugs in PHPbrew but I did send them a full pull requests to make my default expectations match up with what they were offering. There were a few bits that seemed a bit off, but they were all fixed before this article went out. :)

      • pixelBender67

        I didn’t notice any bugs so far. It’s nice to be able to just use a shell to interact with PHP than having to run a VM.
        Especially if your machine is an older dual core model.

    • c9s

      The main reason is there are many library compilation issues on different platform especially 5.3 version.

      and to build PHP from source, you need some patches and configure option tuning to make it work. we’ve spent a lot of time tuning that, and it has become stable.

      • hot_rush

        glad to hear this, you have done a huge job. but i moved to vagrant and looking to a docker

  • http://www.ericlin.me Eric Lin

    Thanks for the post Phil, are PHPBrew and VirtPHP only for the command line? If not, how do they integrate with Apache? Thanks.

    • http://www.bitfalls.com/ Bruno Skvorc

      They are aimed at the command line. But keep in mind that PHP’s built-in server is also “command line”, so running that will actually let you run and test your sites in all the underlying PHP versions and environments you create with PHPbrew and VirtPHP. Apache support is coming soon. See https://github.com/virtphp/virtphp/wiki/Road-Map

    • philsturgeon

      Bruno got it there. They do have plans to support the php-cgi module at some point – therefore bringing Apache into the fold – but for now it is just command-line. You can get quite a long way with that sort of thing.

      I’ll see if I can put together more writing on how you can combine this approach with the Heroku PHP Buildpacks, and get nginx and Apache into the fold. I’m fairly confident its possible based on what I’ve been doing previously.

  • banjax

    really should label this Mac only; useless for windows users, not that useful for Linux.

  • tysweezy

    Nice stuff Phil! virtPHP reminds me of virtualenv for Python.

  • http://pinoysmartlife.com/ Thorpe

    Interesting projects. PHP makes me wanna get interested again.

  • https://github.com/jk Jens

    How does phpbrew + virtphp differ from phpbuild + phpenv? I liked that phpbuild can have its own PEAR installation for every installed php version.

  • pixelBender67

    Awesome!

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in PHP, once a week, for free.