Système d'exploitation : Fedora 39 Workstation x86_64 (mais les exemples fonctionnent aussi sur RHEL, Alma Linux, Rocky Linyx et CentOS Stream version 8 ou 9)

Dépôts tiers : rpmfusion (pour écouter de la musique en travaillant) et évidement remi

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

Pour RHEL, Alma, Rocky ou CentOS, lisez les instructions de l'assistant de configuration.

 

Installation des versions de PHP

J'utilise les Software Collections qui permettent d'installer plusieurs versions en parallèle sans toucher au système de base, les versions de PHP 7.4 à 8.4 sont disponibles dans mon dépôt, donc:

# dnf install php php-fpm php-mbstring php-mysqlnd ...
# dnf install php74 php74-php-fpm php74-php-mbstring php74-php-mysqlnd ...
# dnf install php80 php80-php-fpm php80-php-mbstring php80-php-mysqlnd ...
# dnf install php81 php81-php-fpm php81-php-mbstring php81-php-mysqlnd ...
# dnf install php82 php82-php-fpm php82-php-mbstring php82-php-mysqlnd ...
# dnf install php83 php83-php-fpm php83-php-mbstring php83-php-mysqlnd ...
# dnf install php84 php84-php-fpm php84-php-mbstring php84-php-mysqlnd ...

 

Configuration de l'environnement Web

 

PHP FastCGI Process Manager

Je n'utilise plus mod_php depuis longtemps car il n'autorise qu'une seule version du module, mais FPM qui est aussi utilisé par défaut dans Fedora et EL ≥ 8.

Je ne suis pas en production mais sur une station de développement, donc afin de limiter la charge, je modifie la configuration de chaque FPM pour utiliser le mode "ondemand". Chaque version utilise un fichier port différent.

Example, pour PHP 7.4, dans le fichier /etc/opt/remi/php74/php-fpm.d/www.conf

listen = /var/opt/remi/php74/run/php-fpm/www.sock
pm = ondemand

Et ensuite j'active le service

# systemctl enable --now php74-php-fpm

Et j'applique pour chaque version.

Apache

Je crée 1 hôte virtuel pour chaque version de PHP

Dans le fichier /etc/hosts, déclaration des alias IP

127.0.0.1    php74scl php80scl php81scl php82scl php83scl php84scl

Création d'un fichier de configuration, avec les alias vers les dépôts git dans lesquels je travaille, ainsi que les hôtes virtuels: /etc/httpd/conf.d/remi.conf

    <VirtualHost *:80>
        ServerName localhost
        <FilesMatch \.php$>
            SetHandler "proxy:unix:/var/run/php-fpm/www.sock|fcgi://localhost"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php74scl
        <FilesMatch \.php$>
            SetHandler "proxy:unix:/var/opt/remi/php74/run/php-fpm/www.sock|fcgi://php74scl"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php80scl
        <FilesMatch \.php$>
            SetHandler "proxy:unix:/var/opt/remi/php80/run/php-fpm/www.sock|fcgi://php80scl"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php81scl
        <FilesMatch \.php$>
            SetHandler "proxy:unix:/var/opt/remi/php81/run/php-fpm/www.sock|fcgi://php81scl"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php82scl
        <FilesMatch \.php$>
            SetHandler "proxy:unix:/var/opt/remi/php82/run/php-fpm/www.sock|fcgi://php82scl"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php83scl
        <FilesMatch \.php$>
            SetHandler "proxy:unix:/var/opt/remi/php83/run/php-fpm/www.sock|fcgi://php83scl"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php84scl
        <FilesMatch \.php$>
            SetHandler "proxy:unix:/var/opt/remi/php84/run/php-fpm/www.sock|fcgi://php84scl"
        </FilesMatch>
    </VirtualHost>

Et j'utilise donc les adresses http://php74scl/, http://php80scl/, http://php81scl/, http://php82scl/, http://php83scl/ et http://php84scl/ dans mon navigateur. Chaque hôte sert les mêmes pages, mais avec la version choisie de PHP. Tous les hôtes fonctionnent en même temps.

 

Ligne de commande

Pour passer d'une version à l'autre, je choisi simplement la version voulue en utilisant les modules d'environnements

$ module load php82
$ ...
$ module unload php82

Développement sur du code PHP

J'utilise évidement les outils disponibles dans le dépôt, et qui sont prévus pour fonctionner avec le PHP disponible.

# dnf install composer phpunit10 phpunit11 phpcompatinfo phpcs ...

Par exemple :

$ git clone https://github.com/vendor/project.git
$ cd project
$ composer install
$ module load php74
$ vendor/bin/phpunit --verbose
$ module load php84
$ vendor/bin/phpunit --verbose
$ ...

Développement des extensions PHP

Il faut évidement installer les outils de développement

# dnf install php74-php-devel php80-php-devel php81-php-devel php82-php-devel php83-php-devel php84-php-devel

Par exemple :

$ cd /work/GIT/rpminfo
$ module load php84
$ phpize
$ ./configure
$ make
$ make test

 

Conclusion

Cette configuration, qui me parait simple, me semble idéale pour un développeur qui a besoin de plusieurs versions de PHP mais veut se concentrer sur son travail, et bénéficier de l'ensemble des paquets disponibles dans une distribution assez complète, avec le bénéfice des Software Collections disponibles dans mon dépôt.

J'aurais aussi pu utiliser Docker... mais cette solution me semble bien plus simple, enfin j'utilise quand même Docker pour PHP 5.3.