mehrere PHP gleichzeitig betreiben (Apache)

Anleitung, wie man unter AlmaLinux 9 (oder andere RHEL Clones) und Apache mehrere PHP-Versionen gleichzeitig auf einem Server betreiben kann, unterschieden nach VirtualHost, Verzeichnissen oder sogar Dateiendungen.

Als erstes muss das EPEL Repository installiert werden:

dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
dnf install http://rpms.remirepo.net/enterprise/remi-release-9.rpm

Die Anleitung funktioniert auch unter RHEL Clones, dazu muss die "9" in den URLs durch eine "8" ersetzt werden. In den folgenden Schritten gibt es keinen Unterschied zwischen EL8 und EL9.

Nun können die gewünschten PHP-Versionen inkl. Module installiert werden. EL8 ab PHP 5.6, EL9 ab PHP 7.4. Die Versionsnummer ist dabei stets 2-stellig geschrieben, php74-php steht also für Version 7.4.x, php80.php für Version 8.0.x. Notwendig ist einzig phpXX-php, andere Module sind optional.

dnf install php74-php php74-php-zip php74-php-imagick php74-php-mbstring php74-php-mcrypt php74-php-mysql

Diesen Schritt für alle gewünschten Versionen wiederholen.

Die php.ini Dateien befinden sich jeweils unter /etc/opt/remi/phpXX/php.ini, wobei XX wieder für die 2-stellige Versionsnummer steht. Das Binary befindet sich unter /usr/bin/phpXX-cgi, auch hier ist XX wieder die Versionsnummer.

Als nächstes muss pro PHP-Version ein Wrapper-Script erstellt werden. Dazu wird zuerst mal ein Verzeichnis erstellt:

mkdir /var/www/php-wrapper

und darin pro Version eine eigene Datei /var/www/php-wrapper/phpXX.fcgi mit folgendem Inhalt

#!/bin/bash
exec /bin/phpXX-cgi

Dann das Script noch dem Apache-User zuordnen uns ausführbar machen:

chown apache.apache /var/www/php-wrapper
chown apache.apache /var/www/php-wrapper/phpXX.fcgi
chmod 755 /var/www/php-wrapper/phpXX.fcgi

XX steht auch hier überall für die 2-stellige PHP-Version.

Damit die PHP-Version genauer gesteuert werden kann löscht man die Dateien /etc/httpd/conf.d/php81-php.conf und erstellt dafür eine neue Datei /etc/httpd/conf.d/multiphp.conf mit folgendem Inhalt:

ScriptAlias /php-wrapper/ "/var/www/php-wrapper/"

<Directory "/var/www/php-wrapper">
  AllowOverride All
  Options +ExecCGI
  AddHandler cgi-script .fcgi
</Directory>

<Directory "/var/www/html">
  AddHandler php74-fcgi .php74
  AddHandler php80-fcgi .php80
  AddHandler php81-fcgi .php81
  AddHandler php82-fcgi .php82
  Action php74-fcgi /php-wrapper/php74.fcgi
  Action php80-fcgi /php-wrapper/php80.fcgi
  Action php81-fcgi /php-wrapper/php81.fcgi
  Action php82-fcgi /php-wrapper/php82.fcgi

  AddHandler php74-fcgi .php
  <FilesMatch \.(php|phar)$>
    SetHandler None
  </FilesMatch>

</Directory>

In der Datei natürlich nur die installierten PHP-Versionen auflisten. Mit der AddHandler-Zeile auf die Dateiendung .php definiert man die PHP-Version für PHP-Dateien (fett; in diesem Beispiel PHP 7.4.xx).

Mit einem Neustart von Apache mittels

systemctl restart httpd.service

wird dies wirksam. Nun sind im definierten Verzeichnis die Dateiendungen .php, .php74, .php80, .php81 und .php82 erlaubt und führen die jeweilige PHP-Version aus. Dazu erstellt man am besten einfach ein paar Testdateien /var/www/html/phpinfo.php/var/www/html/phpinfo.php74/var/www/html/phpinfo.php80/var/www/html/phpinfo.php81 und /var/www/html/phpinfo.php82 jeweils mit folgendem Inhalt

<?php
phpinfo();

und ruft diese via Browser auf.

Für einzelne VirtualHosts kann man dies nun pro Verzeichnis definieren und sofern AllowOverride auf All gesetzt ist kann sogar in einem beliebigen Unterverzeichnis eine .htaccess Datei mit folgendem Inhalt erstellt werden:

AddHandler php81-fcgi .php

Dies führt dazu, dass alle Dateien mit der Dateiendung .php in diesem Verzeichnis (und darunterliegenden Verzeichnissen) mit PHP 8.1.xx ausgeführt werden. Dadurch kann die PHP-Version via Dateiendung in einem Verzeichnis oder via Konfiguration für die Dateiendung .php in einem VirtualHost oder pro Verzeichnis individuell gesteuert werden.