Building a Better PHP — Part 2: Using HHVM

Building a Better PHP — Part 2: Using HHVM

Using HHVM

Continuing on from part one in our series, now that we have a working HHVM environment, we can start to use it for something more practical than phpinfo().

Composer

One of the first things you can do today to improve your workflow, is to start using HHVM for composer. As noted in numerous tweets. This will make composer run faster, and use less resources. And, as this is a standalone process, it is easy to switch away from PHP.net – and more importantly, switch back if things go awry.

First, lets start by installing Composer. Because HHVM defaults to a 5000ms HTTP request timeout, we will want to change this setting.

To change this, we need to set the Http.SlowQueryThreshold configuration option.

We can set it in the server.hdf config (affecting all requests) by adding:

Http {
  SlowQueryThreshold = 30000
}

Or, we can do it via the command line using the -v flag, or if using --php flag to emulate PHP’s CLI, the -d flag:

$ hhvm -v Http.SlowQueryThreshold=30000
or
$ hhvm --php -dHttp.SlowQueryThreshold=30000

Note: You may require a higher threshold depending on your internet connection

We then have to install a couple of dependencies:

$ sudo apt-get install curl git unzip

Now to install Composer, we can simply do:

$ curl -sS https://getcomposer.org/installer | sudo hhvm --php -dHttp.SlowQueryThreshold=30000
$ sudo mv composer.phar /usr/local/bin/composer

This uses the --php flag to allow us to pipe the Composer installer code directly into HHVM.

Next, we setup an alias for composer to allow us to run it via HHVM, and to set two network configuration variables to alleviate most issues with slower connections.

Additionally, we set the Eval.Jit=false as the JIT is only beneficial to long-running processes when used on the CLI, and would in the case of composer cause the HHVM startup to be slower.

alias composer="hhvm -v ResourceLimit.SocketDefaultTimeout=30 -v Http.SlowQueryThreshold=30000 -v Eval.Jit=false /usr/local/bin/composer"

To make this permanent, you should add this line to ~/.bashrc and run source ~/.bashrc.

We can then run composer and setup our project, using for example the Zend Framework 2 Skeleton Application:

$ composer create-project --prefer-source zendframework/skeleton-application:dev-master /var/www/zf2

Note: I got an ErrorException “Undefined variable: inputStream”, however it completed successfully none-the-less.

Setting up our Web Server for Zend Framework 2

Next, we update our Nginx and hhvm server configurations to point to the ZF2 document root, /var/www/zf2/public.

For Nginx, edit /etc/nginx/sites-available/hhvm.conf and change the following two lines:

root /var/www/zf2/public;

# Inside the location block
fastcgi_param SCRIPT_FILENAME /var/www/zf2/public$fastcgi_script_name;

For HHVM, we change the Server.SourceRoot configuration to:

SourceRoot = /var/www/zf2/public

Next, restart both services:

$ sudo service nginx restart
$ sudo service hhvm restart

Note: prior to the HHVM 3.0 the init scripts for Ubuntu (at least) were broken. Instead, you should use sudo killall hhvm && sudo service hhvm start to restart.

If you access the web server in your browser again, you will see the default ZF2 Skeleton Application:

ZF2 Skeleton App

Now you can start to develop a new ZF2 application.

PHPUnit

Another common task that can be improved by switching to HHVM is running your unit tests.

To do this, first install PHPUnit using Composer:

$ composer global require 'phpunit/phpunit=4.0.*'

To complete the installation, add the following alias to your ~/.bashrc and run source ~/.bashrc:

alias phpunit='hhvm -v Eval.Jit=false /home/vagrant/.composer/vendor/bin/phpunit'

Now, the phpunit command will be run via HHVM, just like Composer.

If we want to run the ZF2 test suite, we can do so by running the following:

$ cd /var/www/zf2/vendor/zendframework/zendframework
$ composer install
$ cd tests/
$ phpunit

Using FastCGI with UNIX Sockets

With the next version of HHVM (3.0, scheduled for March 27th) we will see support for FastCGI over UNIX sockets.

UNIX Sockets should (in theory) perform better than TCP sockets, and are easy to use. If you choose to make this change, be sure to benchmark before and after the change to ensure that you are actually seeing performance increases, or resource usage decreases.

To use UNIX sockets, we again need to change our server configs. For HHVM, change /etc/hhvm/server.ini like so:

; hhvm.server.port = 9000
hhvm.server.file_socket = /var/run/hhvm/server.sock

For Nginx, change /etc/nginx/sites-available/hhvm.conf:

location ~ \.(hh|php)$ {
  # fastcgi_pass 127.0.0.1:9000;
  fastcgi_pass unix:/var/run/hhvm/server.sock;
  ...
}

Then just restart the daemons again:

$ service hhvm restart
$ service nginx restart

Note: To use this feature now, you must install a current nightly build (the VagrantFile will do this by default).

Coming up next…

As well as an overview of using HHVM to replace PHP.net, we now have two practical applications for HHVM that we can put into use immediately.

In the next part in this series, we will take an in-depth look at hack and the features it brings to the table — as well as review what they might mean for PHP.net.

Have you tried HHVM yet? What are your experiences? What do you think about HHVM so far? Let us know in the comments.

About Davey Shafik

Davey Shafik is a full time PHP Developer with 12 years experience in PHP and related technologies. A Community Engineer for Engine Yard, he has written three books (so far!), numerous articles and spoken at conferences the globe over.

Davey is best known for his books, the Zend PHP 5 Certification Study Guide and PHP Master: Write Cutting Edge Code, and as the originator of PHP Archive (PHAR) for PHP 5.3.