PHP 7.2 on Debian Stretch

Debian’s emphasis on stability makes it an ideal web server operating system. Frozen library versions mean fewer updates, fewer disruptions, and in general, fewer surprises. But on the other hand, this extreme stability can sometimes cause it to fall (too far) behind the pace of upstream development.

As was the case with Debian Jesse, Stretch ships a version of PHP that is quickly nearing its official End of Life. Once that December deadline passes, the number of developers contributing bug and security fixes to PHP 7.0 will plummet, potentially leaving users vulnerable to attack.

That is bad. Haha.

Upgrade to PHP 7.2

Luckily, PHP 7.2 is only a third-party repo away:

# Get the key.
wget -qO - https://packages.sury.org/php/apt.gpg | sudo apt-key add -

# Add the apt source.
sudo echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list

# Update.
sudo apt-get update

# Install what you need...
sudo apt-get install php7.2…

PHP 7.0 and 7.2 follow the same package-naming conventions and place their configuration files in version-specific folders (e.g. /etc/php/7.2/), making it fairly easy to migrate from one to the other.

That said, at the time of this writing, the phpmyadmin package provided by Debian is incompatible with PHP 7.2. For the time being, you’ll either need to uninstall that package and manually download the latest release, or add the Blobfolio apt repo to your sources:

# Get the key.
wget -qO - https://apt.blobfolio.com/public.gpg.key | sudo apt-key add -

# Add the apt source.
echo "deb [arch=amd64] https://apt.blobfolio.com/debian/ stretch main" | sudo tee /etc/apt/sources.list.d/blobfolio.list

# Update sources and phpmyadmin.
sudo apt-get update && sudo apt-get install phpmyadmin

But is it better?

The jump from PHP 5.6 to 7.0 was pretty damn impressive. Not only did it bring a shitload of useful, new features, it also managed to significantly decrease resource consumption while improving overall performance.

Unfortunately, that is probably a once in a lifetime event. Haha.

PHP 7.2 is an improvement over 7.0, but a much more modest one.

Debian Strech, PHP-FPM 7.2.5 relative to 7.0.27. Lower (left) is better.

We pulled several weeks of resource usage and response time data — before and after the upgrade — from every server in our fleet. That was a bit too much to squeeze into a graph for the blog, however, so we narrowed it to three servers, each representative of a common type of workload, but different enough from one another to help give a sense of variability. In order, we have low- and high-traffic multi-site servers, and one high-traffic single-site server.

Adjusting for variations in traffic, we found modest but consistent decreases in both CPU (2.75%) and memory consumption (1.18%) across the board.

The average response time for PHP document requests proved more dramatic, but also more variable. As you can see from the above, the first server’s response times only improved 2.27%, while the others enjoyed 10× that.

So why the difference?

Priming

A web server operates kind of like the United Nations. In order to execute a PHP script, an interpreter must first translate the human-readable PHP syntax into lower level machine code. As you might expect, this adds a lot of runtime overhead, culminating in slower request processing.

The performance magic started by PHP 7.0 — and continued through PHP 7.2 — is largely achieved by caching as much of this machine code as possible. In this way, subsequent executions of a given script can be processed much more quickly.

While heavy traffic can place strain on many aspects of a server, for PHP at least, it can help speed things up. On the whole, PHP 7.2 is faster than PHP 7.0, but the effects are more pronounced under load.

Is It Worth It?

Modest improvements are still improvements, so yes, you should probably consider upgrading. Plus if nothing else, switching to a supported branch of PHP will ensure timely updates for years to come.

But that said, every upgrade introduces the risk of breaking changes. Before pulling the trigger, be sure to review the list of such changes for both 7.1 and 7.2.

For our own servers, it has largely been smooth sailing, but there are two compatibility issues we have encountered in the wild.

While count() was only ever intended to be applied to countable objects — duh! — PHP 7.2 now officially outlaws any off-label uses. While it is stupid to have misused this function intentionally, it is very easy to misuse it accidentally. Older versions of major programs such as WordPress and phpMyAdmin were both guilty of this, though each have since fixed the issue. (Unless you’re still relying on Debian-provided packages, haha.)

Less common, but still a thing: PHP 7.1 no longer allows appending data to a string using index-free array-like syntax. This is a little harder to visualize, so here is an example:

$str = 'Hello World';

// Appropriate ways to append an "!" to the string:
$str .= '!';
$str[11] = '!';

// PHP Fatal error:  Uncaught Error: [] operator not supported
// for strings
$str[] = '!';

But hey, such is progress. 🙂