Operating system: Fedora 25 Workstation x86_64 (but the examples also work on RHEL or CentOS 7)

3rd party repositories: rpmfusion (to listen music while I work) and of course remi

# wget http://rpms.remirepo.net/fedora/remi-release-25.rpm
# dnf install remi-release-25.rpm
# dnf config-manager --set-enabled remi

For RHEL or CentOS, instead, read the Configuration Wizard instructions.

 

Installation of the PHP versions

I use the Software Collections which allow to install multiple versions, in parallel, without affecting the base system, PHP version 5.4, 5.5, 5.6, 7.0 and 7.1 are available in my repository, so:

# yum install php56 php56-php-fpm php56-php-mbstring php56-php-mysqlnd ...
# yum install php70 php70-php-fpm php70-php-mbstring php70-php-mysqlnd ...
# yum install php71 php71-php-fpm php71-php-mbstring php71-php-mysqlnd ...
# yum install php72 php72-php-fpm php72-php-mbstring php72-php-mysqlnd ...
# yum install php73 php73-php-fpm php73-php-mbstring php73-php-mysqlnd ...
# yum install php74 php74-php-fpm php74-php-mbstring php74-php-mysqlnd ...

RHEL users can also install the official SCL available in the RHSCL channel (php54, php55, rh-php56, rh-php70, rh-php71 and rh-php72).

CentOS users can also install the SCL, maintained by the SIG, available in the centos-sclo-sclo repository.

 

Web environment configuration

PHP FastCGI Process Manager

I don't use mod_php which only allow a single version, but FPM.

I'm not running a production server, but a development workstation, so, to reduce the load, I change the FPM pool configuration to use the "ondemand" mode. I also use a specific port for each version.

Example, for PHP 7.0, in the  /etc/opt/remi/php70/php-fpm.d/www.conf file:

listen = 127.0.0.1:9070
pm = ondemand

I also configure SElinux context for this port:

# semanage port -a -t http_port_t -p tcp 9070

And I enable the service:

# systemctl start php70-php-fpm
# systemctl enable php70-php-fpm

And apply the same for each version.

Apache

I create a virtual host for each PHP version.

In the /etc/hosts file, IP aliases declaration:

192.168.0.15    myip php74scl php73scl php72scl php71scl php70scl php56scl

I create a configuration file, with alias to the git repositories in which I'm used to work, and the virtual hosts: /etc/httpd/conf.d/remi.conf

    Alias /glpi090    "/work/GIT/GLPI/090-bugfixes"
    Alias /glpimaster "/work/GIT/GLPI/master"
    Alias /galette    "/work/GIT/galette/galette"

    <Directory "/work/GIT">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride All
        Require local
    </Directory>

    <VirtualHost *:80>
        ServerName php74scl
        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://127.0.0.1:9074"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php73scl
        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://127.0.0.1:9073"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php72scl
        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://127.0.0.1:9072"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php71scl
        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://127.0.0.1:9071"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php70scl
        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://127.0.0.1:9070"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php56scl
        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://127.0.0.1:9056"
        </FilesMatch>
    </VirtualHost>

And then, I can use the http://php74scl/, http://php73scl/, http://php72scl/, http://php71scl/, http://php70scl/ and http://php56scl/ addresses in my browser. Each host serves the same pages, but with the selected version. All hosts work simultaneously.

Warning: ensure your configuration file is loaded after the php*.conf. You may have to comment the SetHandler directives there (since Fedora 27, which use FPM by default).

 

Command line

To switch from one version to another, I simply select the desired version using the environment modules:

$ module load php70
$ ...
$ module unload php70

Working on PHP code

Of course, I use the development tools available in the repository which are designed to work with the available PHP version.

# yum install atoum composer phpunit phpcompatinfo phpcs apigen ...

For example :

$ git clone https://github.com/vendor/project.git
$ cd project
$ composer install
$ module load php73
$ phpunit --verbose
$ module load php70
$ phpunit --verbose
$ ...

Working on PHP extensions

Of course, the development packages need to be installed:

# yum install php74-php-devel php73-php-devel php72-php-devel php71-php-devel php70-php-devel php56-php-devel

For example :

$ cd /work/GIT/uopz
$ module load php71
$ phpize
$ ./configure
$ make
$ make test

 

Conclusion

I think this configuration, which seems simple, is the ideal solution for a developer who needs various PHP versions but want  to be focused on his work, and take benefits of the large set of available packages in a quite full featured distribution, with benefits of available Software Collections in my repository.

I could also have used Docker... but this solution seems more simple, indeed, I sometime use Docker for PHP 5.3.