#hhvm

PHP is an interesting language, and to many it is considered a language that is archaic and badly designed. In fact, I largely agree that PHP's design is not optimal, but there is no other language in the world that is both easy to learn and deployable on almost any shared hosting service so easily. This is changing, but for now, PHP is here to stay.

By design, PHP does not have explicit typing-- a variable can be any type, and can change to any type at any time. This is in stark contrast to other languages, such as Apple's Swift, Java, and many others. Depending on your background, you may consider PHP's lack of explicit typing to be dangerous.

Not only this, but PHP is not the most performant language by any means. You can see this for yourself in TechEmpower's famous framework benchmarks. These results clearly show that PHP is at or near the bottom of the pile, being beat outright by languages such as Java and Go.

So, how do you make one of the most popular languages in the world for web applications usable again? Many say that PHP simply needs to be killed off entirely, but Facebook disagrees.

HHVM is a project designed to revitalize PHP. HHVM often beats PHP in performance benchmarks, and supports a new explicitly typed language-- Hack. Hack, sometimes referred to as "Hacklang" so that it you can actually search for it on Google, is almost completely compatible with standard PHP. With the exception of a few quarks, any PHP file can also be a valid Hack file. From there, you can take advantage of new features such as explicit typing, collections, and generics. For example:

<?hh

class MyClass {
public function add(int $one, int $two): int {
return $one + $two;
}
}

As you can see, Hack is very similar to PHP. In fact, Hack is really just an extension of PHP since you can simply begin any PHP code with the <? hh tag to make it a valid Hack file.

So, how do you get started with HHVM and Hack? Unfortunately, Mac OS X and Windows binaries are not provided officially, and though you can install HHVM yourself by compiling it on Mac, it's certainly not the most convenient. An even better way of trying out Hack is to simply use a Linux server. One of my go-to providers for cheap "testing" servers on demand is DigitalOcean, who provides SSD cloud servers starting at $0.007 an hour. Of course, this tutorial applies to any server provider or even a local VM, so you can follow the steps regardless who your provider is.

Booting Up a Server

First, you'll need an Ubuntu server-- preferably 14.04, though any version from 12.04 up will work fine, as does many other flavors of Linux.

On DigitalOcean, you can get started by registering a new account or using your existing one. If you're a new user to DigitalOcean, you may even be able to find a coupon code for $5-$10 in credit (such as the coupon code ALLSSD10, which should be working as of July 2014).

Once you've registered on DigitalOcean, you can launch a new "Droplet" (DigitalOcean's term for a virtual machine or VPS) with the big green "Create" button on the left side of your dashboard.

Go ahead and enter any hostname you want, and choose a server size. You can also choose any Droplet size you wish, including the baseline 512 MB RAM Droplet. If you're planning on running anything in production on this server or wish to have a little more headroom, you may wish to choose the slightly larger 1 GB RAM Droplet.

Next, you can choose the region closest to yourself (or your visitors if you're using this as a production server). DigitalOcean has six different data centers at the moment, including New York, San Francisco, Singapore, and Amsterdam. Different data centers have different features such as private networking and IPv61, though these features are slated to roll out to all data centers at some point in time.

Finally, choose the Ubuntu 14.04 image and create your Droplet. It'll only take around 60 seconds to do so, and once the Droplet is running SSH into the server using the credentials sent to you or your SSH key if you've set up SSH authentication.

Installing HHVM

HHVM is relatively easy to install on Ubuntu, but varies based on your Ubuntu version. The main difference between the commands below is simply the version name when adding the repository to your sources.

Ubuntu 14.04

wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | sudo apt-key add -
echo deb http://dl.hhvm.com/ubuntu trusty main | sudo tee /etc/apt/sources.list.d/hhvm.list
sudo apt-get update
sudo apt-get install hhvm

Ubuntu 13.10

wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | sudo apt-key add -
echo deb http://dl.hhvm.com/ubuntu saucy main | sudo tee /etc/apt/sources.list.d/hhvm.list
sudo apt-get update
sudo apt-get install hhvm

Ubuntu 13.04

Ubuntu 13.04 isn't officially supported or recommended to use.

Ubuntu 12.04

sudo add-apt-repository ppa:mapnik/boost
wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | sudo apt-key add -
echo deb http://dl.hhvm.com/ubuntu precise main | sudo tee /etc/apt/sources.list.d/hhvm.list
sudo apt-get update
sudo apt-get install hhvm

If you've having issues with the add-apt-repository command on Ubuntu 12.04, then you may need to run sudo apt-get install python-software-properties.

Running HHVM

Once you've installed HHVM, you can run it on the command line as hhvm. Once you create a new Hack file with the following contents, try and run it with hhvm [filename.

<?hh

echo "Hello from HHVM " . HHVM_VERSION;

Note the lack of a closing tag-- in Hack, there are no closing tags and HTML is not allowed inline.

Installing and Setting Up Nginx

Of course, installing HHVM for the command line is the easy part. To actually serve traffic to HHVM using Nginx, you have to set HHVM up as a fast-cgi module. To do so, first install Nginx with sudo apt-get install nginx and start it with sudo service nginx start. To verify that Nginx installed correctly, visit your Droplet's IP address and you should see the Nginx default page.

Now, we can remove the default Nginx websites with the following commands:

sudo rm -f /etc/nginx/sites-available/*
sudo rm -f /etc/nginx/sites-enabled/*

Then, create a new configuration file for your website as /etc/nginx/sites-available/hhvm-site. You can change the name of the configuration file if you wish. The contents of the file should be similar to the one of following:

Emulating "mod_rewrite"

The Nginx equivalent of sending all requests to a single index.php file is as follows. Every request to this server will be sent to the index.php file, which is perfect for frameworks such as Laravel.

server {
    # Running port
    listen 80;
    server_name www.example.com;
# Root directory
root /var/www;
index index.php;

location / {
    try_files $uri @handler;
}

location @handler {
    rewrite / /index.php;
}

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

}

Traditional Setup

In this example, any requests to a script ending in .php will be executed by HHVM. For example, if you have hello.php in your web root, navigating to http://www.example.com/hello.php would cause the hello.php file to be executed by HHVM.

server {
    # Running port
    listen 80;
    server_name www.example.com;
# Root directory
root /var/www;
index index.php;

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

}

Also, ensure that you change all instances of the web root (/var/www) in the above configuration files to your own web root location, as well as the server_name. Alternatively, you can leave the web root as /var/www and just put your Hack files in that folder.

Now that you've created the file under sites-available, you can symlink it to the sites-enabled folder to enable it in Nginx.

sudo ln -s /etc/sites-available/hhvm-site /etc/sites-enabled/hhvm-site

Before you restart Nginx to apply the changes, start the HHVM fast-cgi enabled server with hhvm --mode daemon -vServer.Type=fastcgi -vServer.Port=9000. After the HHVM daemon is started, you can then run sudo service nginx restart to apply your Nginx configuration changes. If you have a Hack file in your web root, you should be able to visit your Droplet's IP and see the response.

Starting HHVM on Boot

HHVM currently does not automatically start up when your server is restarted. To change this, you can simply add the line below into the file named /etc/rc.local to run it on boot:

/usr/bin/hhvm --mode daemon -vServer.Type=fastcgi -vServer.Port=9000

HHVM should now start when your server boots up.

You should now have HHVM and Hack up and running on your server-- make sure you take a look at Hack's documentation for more information on the features of the language.


  1. Singapore is the first region with IPv6 support, while New York 2, Amsterdam 2, and Singapore have private networking.