Who is this for?

  • Linux user
  • Prefer to compile official php7 source code rather than use a docker container or a ppa
  • Want to have both php5 and php7 installed on your system switching between them easily
  • Want to run php5 and php7 on nginx at the same time

Time to cook...

This recipe is a compilation of different tutorials I've found over the Internet. I just added some fancy features and tuned the procedure up to make it work as I expected. However, what you are about to read wouldn't be possible without them, so thanks so much:

Tested on Ubuntu 15.10 and Elementary OS Freya.

Prerequisites

First of all, be root my friend!

sudo su -
Packages
apt-get -y install build-essential autoconf insserv bison git
Libraries
apt-get -y install libgmp-dev libmysqlclient-dev libfcgi-dev libfcgi0ldbl libmcrypt-dev
PHP5

If you have php5 already installed skip this step

apt-get -y install php5 php5-fpm php5-memcached php5-intl php5-mcrypt php5-xdebug php5-mysql
MySQL and Nginx

If you have them already installed or you just don't need them skip this step

apt-get -y install mysql-server mysql-client nginx
Fix gmp
ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h
Php build dependencies

To be able to compile php7 you must add php5 build dependencies

apt-get -y build-dep php5

php5, it's ok, it's not a mistake

Compiling php7

Now you are about to clone official php7 source code. Feel free to choose the path you want.

Clone repository
git clone https://git.php.net/repository/php-src.git
cd php-src
Compile
./buildconf
./configure --prefix=/usr/local/php7 --localstatedir=/usr/local/var --sysconfdir=/usr/local/etc/php7 --with-config-file-path=/usr/local/etc/php7 --with-config-file-scan-dir=/usr/local/etc/php7/conf.d --mandir=/usr/local/php7/share/man --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-pdo-mysql=/usr --with-gettext=/usr --with-zlib=/usr --with-bz2=/usr --with-recode=/usr --with-mysqli=/usr/bin/mysql_config --with-fpm-user=www-data --with-fpm-group=www-data --enable-fpm --enable-sockets --enable-intl
make
make install

Configuring php7

Now you are going to configure php7. Remember the path where you cloned php7 source code to.

php.ini
cp <path_to_php7_source_code>/php.ini-production /usr/local/etc/php7/php.ini
php-fpm.conf
cp /usr/local/etc/php7/php-fpm.conf.default /usr/local/etc/php7/php-fpm.conf

Edit following file

/usr/local/etc/php7/php-fpm.conf 

add/edit following line

pid = run/php-fpm.pid
www.conf
cp /usr/local/etc/php7/php-fpm.d/www.conf.default /usr/local/etc/php7/php-fpm.d/www.conf

Edit following file

/usr/local/etc/php7/php-fpm.d/www.conf

add/edit following lines

;listen = 127.0.0.1:9000
listen = /var/run/php7-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

Service scripts

php7-fpm

Create following file

/etc/init.d/php7-fpm
#! /bin/sh
### BEGIN INIT INFO
# Provides:          php7-fpm
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts php7-fpm
# Description:       starts the PHP FastCGI Process Manager daemon
### END INIT INFO
php_fpm_BIN=/usr/local/php7/sbin/php-fpm
php_fpm_CONF=/usr/local/etc/php7/php-fpm.conf
php_fpm_PID=/usr/local/var/run/php-fpm.pid
php_opts="--fpm-config $php_fpm_CONF"
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
php7-fpm permissions
chmod 755 /etc/init.d/php7-fpm
php7-fpm enable
/usr/lib/insserv/insserv php7-fpm
php7-fpm.service

Create following file

/lib/systemd/system/php7-fpm.service
[Unit]
Description=The PHP 7 FastCGI Process Manager
After=network.target

[Service]
Type=simple
PIDFile=/usr/local/var/run/php-fpm.pid
ExecStart=/usr/local/php7/sbin/php-fpm --nodaemonize --fpm-config /usr/local/etc/php7/php-fpm.conf
ExecReload=/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target
Start php7-fpm service

If you system supports systemctl then run following commands

systemctl enable php7-fpm.service
systemctl daemon-reload
service php7-fpm start

If not, just run command below

/etc/init.d/php7-fpm start
Socket owner
chown www-data. /var/run/php7-fpm.sock

You can configure php5 and php7 in different nginx virtual hosts at this moment. Just follow these steps

Add hosts

Edit hosts file

/etc/hosts

Add following line

127.0.0.1 php5 php7
Add nginx virtual hosts

php5

server {
	listen *:80;
	root /var/www/html;
	index index.php index.html index.htm index.nginx-debian.html;
	server_name php5;
	location / {
		try_files $uri $uri/ =404;
	}
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
		fastcgi_pass unix:/var/run/php5-fpm.sock;
	}
}

php7

server {
	listen *:80;
	root /var/www/html;
	index index.php index.html index.htm index.nginx-debian.html;
	server_name php7;
	location / {
		try_files $uri $uri/ =404;
	}
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
		fastcgi_pass unix:/var/run/php7-fpm.sock;
	}
}

Restart nginx and try following urls on your browser:

Switch between php5 and php7

Despite of nginx can run on php5 and php7 sockets, to set php system running version (cli) follow these steps

Add php7 as an alternative
update-alternatives --install "/usr/bin/php" "php" "/usr/local/php7/bin/php" 1 
Configure system php version

You can select system php version by running command below. You'll be asked to choose between available options, select php5 or php7

update-alternatives --config php
Check php version
php -v

And that's all folks!