After major parts of the PHP community were against releasing PHP6 as the successor of PHP5, the new official replacement of PHP5 will now be PHP7. A first beta version is now available and the final release is planned on October 2015. Because there are no official packages to be installed for Debian or Ubuntu at the moment, we’ll create a PHP 7 php-fpm module by compiling the beta 1 source code. That will also allow us to continue having PHP5 on our server as the main version but use PHP7 to test our projects for compatibility.
Update PHP 7.0.0: Installing the final PHP 7 as a php-fpm module on a Ubuntu 14.04 LTS system
For a first glimps of the new features and changes of PHP 7 I suggest reading the following article form the Zend Homepage: Coolest PHP 7 Features
1. Download
The most recent source code is available via the official Git Repository. Instead we will use the first Beta Version from the PHP Servers for now.
cd /usr/local/src wget wget https://downloads.php.net/~ab/php-7.0.0beta1.tar.bz2 tar -jxf php-7.0.0beta1.tar.bz2 cd php-7.0.0beta1
The source code was now downloaded and extracted and we changed into the new directory.
2. Configure the source code
We’ll need a lot of support packages to compile the code successfully. With the following commands all of the needed modules should be installed.
sudo aptitude build-dep php5 sudo apt-get install libc-client2007e-dev libmcrypt-dev openssl courier-imap libgmp-dev checkinstall
Now we can configure the source code.
./configure --prefix=/opt/php7 \ --with-config-file-path=/etc/php7 \ --with-config-file-scan-dir=/etc/php7/conf.d \ --disable-short-tags \ --enable-mbstring \ --enable-zip \ --enable-bcmath \ --enable-pcntl \ --enable-ftp \ --enable-exif \ --enable-calendar \ --enable-sysvmsg \ --enable-sysvsem \ --enable-sysvshm \ --enable-wddx \ --with-curl \ --with-mcrypt \ --with-iconv \ --with-gmp \ --with-pspell \ --with-gd \ --with-jpeg-dir=/usr \ --with-png-dir=/usr \ --with-zlib-dir=/usr \ --with-xpm-dir=/usr \ --with-freetype-dir=/usr \ --enable-gd-native-ttf \ --enable-gd-jis-conv \ --with-openssl \ --with-imap \ --with-imap-ssl \ --with-pdo-mysql=/usr \ --with-gettext=/usr \ --with-zlib=/usr \ --with-bz2=/usr \ --with-kerberos \ --with-mysqli=/usr/bin/mysql_config \ --enable-fpm
Known issues during the configuration process
Error:
configure: error: Unable to locate gmp.h
Solution:
Create a symbolic link.
ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h
3. Compile
This will take some time. If make has finished without errors we’ll use checkinstall to create a Debian/Ubuntu package file that will contain all the new files we just created. That way we’ll also be able to remove the files again easily using a package manager of our choice.
make checkinstall
checkinstall will ask for a package name, a maintaner and a description. As package name I would suggest using php7 to avoid conflicts with existing PHP installations. After that a .deb file will be created and also installed on our system.
The remove the changes again we can simply use:
apt-get remove php7
4. First tests
The most simple test would be using the command line interface (CLI)
/opt/php7/bin/php -v
This should return version information like version numebr PHP 7.0.0beta1. The next command will return data regarding the installed modules as well as configuration paramenters.
/opt/php7/bin/php -v
5. Using the php-fpm module with Apache and fastcgi
We’ll assume that the Apache webserver is installed an running. First we’ll install the fastcgi module and enable the action module.
apt-get install apache2-mpm-worker libapache2-mod-fastcgi a2enmod action
Next step is to create config files for php-fpm and start the process.
cd /opt/php7/etc sudo cp php-fpm.conf.default php-fpm.conf sudo cat php-fpm.d/www.conf.default | sed s/nobody/www-data/ > php-fpm.d/www.conf sudo ../sbin/php-fpm
With that we have created a www.conf file defining a process pool. We replaced the user and group values nobody with www-data and launched the php-fpm process. If the system already has a php-fpm module installed, for example PHP5, we should also change the port number in that file.
The only thing left is now to add the following line into a VirtualHost configuration of our choice.
... # This will override the default php5 handler from php5.conf <FilesMatch ".+\.ph(p[345]?|t|tml)$"> SetHandler php7-fcgi # Add Action to route requests to php-fpm Action php7-fcgi /php7-fcgi # php7.fcgi doesn't have to exit but the folder does and needs to be within # document root Alias /php7-fcgi /var/www/php7.fcgi FastCGIExternalServer /var/www/php7.fcgi -host 127.0.0.1:9000 ...
Instead of /var/www you have the use the real path to our DocumentRoot folder. Apache needs to be restarted for the changes to take effect.
Example Initscript for our new php-fpm server process
#! /bin/sh ### BEGIN INIT INFO # Provides: php-7.0.0beta1-1-fpm # Required-Start: $all # Required-Stop: $all # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: starts php-7.0.0beta1-1-fpm # Description: This starts the PHP FastCGI Process Manager daemon ### END INIT INFO php_fpm_BIN=/opt/php7/sbin/php-fpm php_fpm_CONF=/opt/php7/etc/php-fpm.conf php_fpm_PID=/opt/php7/var/run/php-fpm.pid php_opts="--fpm-config $php_fpm_CONF --pid $php_fpm_PID" wait_for_pid () { try=0 while test $try -lt 35 ; do case "$1" in 'created') if [ -f "$2" ] ; then try='' break fi ;; 'removed') if [ ! -f "$2" ] ; then try='' break fi ;; esac echo -n . try=`expr $try + 1` sleep 1 done } case "$1" in start) echo -n "Starting php-fpm " $php_fpm_BIN $php_opts if [ "$?" != 0 ] ; then echo " failed" exit 1 fi wait_for_pid created $php_fpm_PID if [ -n "$try" ] ; then echo " failed" exit 1 else echo " done" fi ;; stop) echo -n "Gracefully shutting down php-fpm " if [ ! -r $php_fpm_PID ] ; then echo "warning, no pid file found - php-fpm is not running ?" exit 1 fi kill -QUIT `cat $php_fpm_PID` wait_for_pid removed $php_fpm_PID if [ -n "$try" ] ; then echo " failed. Use force-exit" exit 1 else echo " done" echo " done" fi ;; force-quit) echo -n "Terminating php-fpm " if [ ! -r $php_fpm_PID ] ; then echo "warning, no pid file found - php-fpm is not running ?" exit 1 fi kill -TERM `cat $php_fpm_PID` wait_for_pid removed $php_fpm_PID if [ -n "$try" ] ; then echo " failed" exit 1 else echo " done" fi ;; restart) $0 stop $0 start ;; reload) echo -n "Reload service php-fpm if [ ! -r $php_fpm_PID ] ; then echo "warning, no pid file found - php-fpm is not running ?" exit 1 fi kill -USR2 `cat $php_fpm_PID` echo " done" ;; *) echo "Usage: $0 {start|stop|force-quit|restart|reload}" exit 1 ;; esac
You might have to create the following folders manually /opt/php7/var /opt/php7/var/log and /opt/php7/var/run.
6. Use php-fpm with NginX
If your NginX server is already setup to work with a php-fpm process the following lines should be found in the configuration files:
location ~ \.php$ { include /etc/nginx/fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }
In that case you should already have changed the TCP/IP port in the www.pool config file. Just enter the new port instead of 9000 in the NginX configuration. After a reload the VirtualHost should then user PHP7 instead of PHP5.