PHP Elephant by scaldra2 from https://www.flickr.com/photos/7237499@N02/6458472309/sizes/l/. Used under a Creative Commons Attribution-NonCommercial-NoDerivs 2.0 Generic (CC BY-NC-ND 2.0) license.

Hello PHP 7!

With relatively little difficulty, I’m now running PHP 7 alongside PHP 5.6. PHP 7 was released at the beginning of the month, and WordPress was one of the platforms tested against. Given that I can’t stop tinkering with this server’s configuration, I really had no excuse not to set up PHP 7.

Given the myriad services I’m running, I couldn’t switch to PHP 7 outright. While WordPress and YOURLS (powering my url shortener, eth.pw) both support PHP 7, the compatibility list basically ended there.

As I went into this with a fair bit of trepidation (and many backups), what follows is a bit about my experience.

Insights

Support for Redis presented the only complication, as the PECL module I used with PHP 5 isn’t compatible with PHP 7. Fortunately, there’s a PHP 7 branch for the phpredis extension, and that’s working well so far (well enough that you’re reading this, at least). Other than that, passing an appropriate --prefix to ./configure was enough to keep the two versions apart. My init.d script is a derivative of what I had for PHP 5.

Be sure to run ./configure --help first, as I had to enable a few additional extensions/options for my needs.

Build configurations

Purely to demonstrate how I got this done, I’ve included my build configurations for both the main PHP 7 package and phpredis. Fair warning, I probably did something wrong. 😀 I offer no guarantees that this will work, and bear in mind that I did this on a Debian Wheezy box from Linode.

For PHP 7:

./configure --prefix=/usr/local/php7/7.0.0 --with-pdo-pgsql --with-zlib-dir --with-freetype-dir --enable-mbstring --with-libxml-dir=/usr --enable-soap --enable-calendar --with-curl --with-mcrypt --with-zlib --with-gd --with-pgsql --disable-rpath --enable-inline-optimization --with-bz2 --with-zlib --enable-sockets --enable-sysvsem --enable-sysvshm --enable-pcntl --enable-mbregex --enable-exif --enable-bcmath --with-mhash --enable-zip --with-pcre-regex --with-pdo-mysql --with-mysqli --with-mysql-sock=/var/run/mysqld/mysqld.sock --with-jpeg-dir=/usr --with-png-dir=/usr --with-webp-dir --enable-gd-native-ttf --with-openssl --with-fpm-user=www-data --with-fpm-group=www-data --with-libdir=/lib/x86_64-linux-gnu --enable-ftp --with-imap --with-imap-ssl --with-kerberos --with-gettext --with-xmlrpc --with-xsl --enable-opcache --enable-fpm --enable-intl --enable-mysqlnd --with-pear

I know that some of these are redundant, but I tend to be paranoid and prefer as much explicitness as I’m afforded.

For me, the important flags for PHP were --enable-fpm and --enable-mysqlnd. The latter is a bit redundant given the magical combination of other options in that mess above, but since I’m on MySQL 5.6, I wanted to ensure that the native driver was chosen.

For phpredis:

./configure --prefix=/usr/local/php7/phpredis --with-php-config=/usr/local/php7/7.0.0/bin/php-config --enable-redis

PHP configurations

My php-fpm.conf and php-fpm.d/*.conf files are slightly modified versions of what ships with the distribution. I added the following to my php.ini.

php.ini

max_execution_time=30
memory_limit=128M
error_reporting=0
display_errors=0
log_errors=0
user_ini.filename=
realpath_cache_size=2M
cgi.check_shebang_line=0

zend_extension=opcache.so
opcache.enable_cli=1
opcache.save_comments=1
opcache.fast_shutdown=1
opcache.validate_timestamps=1
opcache.revalidate_freq=60
opcache.revalidate_path=1
opcache.use_cwd=1
opcache.max_accelerated_files=100000
opcache.max_wasted_percentage=5
opcache.memory_consumption=64
opcache.consistency_checks=0

extension=redis.so

Errata

To make it easy to build the next release without losing my configurations, I kept all of my files in /etc/php7 and symlinked them to where PHP 7 expected them to be: /usr/local/php7/7.0.0/etc and /usr/local/php7/7.0.0/lib/php.ini. Similarly, I added some symlinks in /usr/bin to make it easier to access PHP 7 via CLI.

When the next version is released, I’ll build it with a new prefix, alongside the existing version. I’ll then symlink the “base” directory I created with version 7.0.0 to the directory for the new release, limiting how many things I need to change with each release. This is, at least, until all of my PHP applications support PHP 7.

Other resources

  • PHP 7 on Debian Jessie – intended for a version before mine, this was helpful for general direction
  • phpredis with PHP 7 – helpful for understanding how I could add Redis support to PHP 7, before I panicked

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

To respond on your own website, enter the URL of your response which should contain a link to this post's permalink URL. Your response will then appear (possibly after moderation) on this page. Want to update or remove your response? Update or delete your post and re-enter your post's URL again. (Learn More)