Více verzí PHP pod jedním Apache serverem

(publikováno 15.08.2017) 6 PHP, Windows

Každý lepší webhosting nabízí možnost vybrat si jakou verzi PHP použít pro spouštění skriptů. Někdy dokonce lze i příponou u souborů vybrat verzi bez ohledu na nastavení. Proč si to tak neudělat i doma?

Více verzí PHP pod jedním Apache serverem

Server Apache dokáže komunikovat s PHP vícero způsoby. Tím nejlehčím a používaným při běžné instalaci je Apache module (mod_php). Pro možnost použití více verzí PHP najednou je ale nutné doinstalovat a použít FastCGI modul. Rozdíly mezi moduly jsou popsány v článku na layershift.com, který je ale v angličtině.

BEZPEČNOSTNÍ UPDATE 17.12.2018 - Použití direktivy AddHandler je potencionálně nebezpečné a mělo by se používat SetHandler. Článek upraven

Každé pro má své pro a proti, což u FastCGI je nemožnost upravovat vlastnosti PHP pomocí .htaccess jako např. php_flag, php_value a pár dalších. Od verze PHP 5.3 to lze vyřešit .user.ini souborem, viz dokumentace. To ale nemusí veřejné hostingy podporovat.

Jsem líný, takže návod začíná v bodě, kdy jsem nainstaloval XAMPP. Návod bude ale fungovat i pro čisté instalace, maximálně se budou nepatrně lišit umístění souborů.
Aktualizace: Vyzkoušeno s PHP 7.3 a stále funguje

Instalace a konfigurace FastCGI i PHP

Prvně je nutné stáhnout fcgid modul pro Apache. Je možné stáhnout zdrojové kódy a provést kompilaci, nebo jednodušeji na ApacheLounge stáhnout binárky. Je nutné vybrat správnou verzi VCxx. Při stahování Apache to je napsáno na webu, u XAMPP je verze shodná pro Apache i PHP, což lze zjistit v phpinfo(); v řádku Compiler. Z archivu stačí zkopírovat soubor mod_fcgid.so a nakopírovat do složky C:\xampp\apache\modules\. Dále doplnit načítání modulu v souboru C:\xampp\apache\conf\httpd.conf.

# Doplnit následující řádek mezi ostatní moduly
LoadModule fcgid_module modules/mod_fcgid.so

Pro použití s FastCGI je vhodné použití non thread safe verze PHP, ale pro Apache module je to naopak, proto v defaultní instalaci XAMPP je thread safe verze. Všechny verze PHP, které budou dostupné je nutné stáhnout znova jako non thread safe z php.net. Zde se již na verzi VCxx shodnou s Apache serverem nemusí brát zřetel. 

Pokud je verze Apache 32 bitová, nejspíše se nepovede zprovoznit 64 bitové PHP 7.

Stažené binárky PHP je nejlepší rozbalit do složky C:\xampp do vhodně pojmenovaných složek php5.6php7.1 apod. Dále v každé nové složce PHP vytvořit soubor php.ini kopií z připraveného development souboru. Ještě je potřeba upravit případné cesty a zvýšit limity, odkazovaný článek je sice pro Linux, nastavení PHP je ale shodné.

Systémová chyba

Pokud po spuštění skriptu pod jinou verzi PHP vyskočí systémová chyba viz obrázek, je potřeba stáhnout a doinstalovat C++ Redistributable knihovny. Stačí vyhledat v Google vc14 redistributable download, a stáhnout z oficiálních stránek Microsoftu. Číslo se může lišit, stačí vzít první 2 číslice z chybějící dll knihovny.

Nastavení Apache

V souboru C:\xampp\apache\conf\extra\httpd-xampp.conf je potřeba provést následující úpravy.
Krok 1: Zakázat mod_php zakomentováním následujících řádků. Komentář se vkládá vložením znaku # na začátek řádku.

LoadFile "C:/xampp/php/php5ts.dll"
LoadFile "C:/xampp/php/libpq.dll"
LoadModule php5_module "C:/xampp/php/php5apache2_4.dll"

<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.phps$">
    SetHandler application/x-httpd-php-source
</FilesMatch>

Krok 2: Konfigurace FastCGI. XAMPP základní konfiguraci obsahuje, tu ale lze smazat, je zakomentována. Na toto místo se vloží řádky níže. Konfigurace navíc obsahuje zápis pro zpracovávání souborů s příponou .php5 verzí PHP 5.6 a nápodobně s příponou .php7 a verzí PHP 7.1. Přípony lze upravit dle libosti na .php56 apod.

<IfModule fcgid_module>
    FcgidInitialEnv PATH "C:/WINDOWS/system32;C:/WINDOWS;C:/WINDOWS/System32/Wbem;"
    FcgidInitialEnv SystemRoot "C:/Windows"
    FcgidInitialEnv SystemDrive "C:"
    FcgidInitialEnv TEMP "C:/xampp/tmp"
    FcgidInitialEnv TMP "C:/xampp/tmp"
    FcgidInitialEnv windir "C:/WINDOWS"
    # FcgidIOTimeout 60 # defaultně 40
    # FcgidMaxProcesses 3 # Každý Wrapper vlastni proces - default 1000
    # Maximální délka požadavku v bytech (dost velké pro upload)
    FcgidMaxRequestLen 134217728
    # Určuje umístění php.ini souboru, ideální nenastavovat
    # FcgidInitialEnv PHPRC "C:/xampp/php5.6/"
    FcgidInitialEnv PHP_FCGI_MAX_REQUESTS 1000

    # Defaultně jsou soubory zpracovávány pod verzí PHP 5.6
    <Files ~ "\.php$">
        Options Indexes FollowSymLinks ExecCGI 
        SetHandler fcgid-script
        FcgidWrapper "C:/xampp/php5.6/php-cgi.exe" .php
    </Files>
    # Soubory s příponou .php5 jsou VŽDY zpracovávány PHP verzí 5.6
    <Files ~ "\.php5$">
        Options Indexes FollowSymLinks ExecCGI 
        SetHandler fcgid-script
        FcgidWrapper "C:/xampp/php5.6/php-cgi.exe" .php5
    </Files>
    # Viz výše, jen s verzí PHP 7.1
    <Files ~ "\.php7$">
        Options Indexes FollowSymLinks ExecCGI 
        SetHandler fcgid-script
        FcgidWrapper "C:/xampp/php7.1/php-cgi.exe" .php7
    </Files>
</IfModule>

V konfiguraci je pár konstant zakomentovaných. První je FcgidIOTimeout, která určuje, jak dlouho může běžet 1 skript, konstanta by měla být větší než max_execution_time v php.ini. Další zakomentovaná konstanta je FcgidMaxProcesses, na různých fórech je nastavena třeba na 4 (počet jader CPU apod). Jenže každý výskyt FcgidWrapper vytvoří nový proces, což u virtual hostů může být dosti časté. Ideální je proto nechat výchozí hodnotu na 1000.

Konstanta FcgidMaxRequestLen by měla být opět rovná nebo vyšší než upload_max_filesize v php.ini. Pokud bude nižší, vyskočí Chyba 500 pro překročení délky požadavku při uploadu větších souborů.

Rovněž nastavení umístění php.ini souboru pomocí proměnné PHPRC není příliš vhodné, protože ovlivní všechny verze PHP najednou. Lze sice používat i u virtual hostů, takže lze mít různé php.ini soubory pro různé weby. Jenže nelze používat uvnitř direktivy <Directory> a <Files>, což přináší nemožnost spouštět různé verze PHP podle přípony. Podle dokumentace PHP vyhledává soubor php.ini v různých složkách včetně té, kde je php.exe či php-cgi.exe. Ideálně tedy umístit php.ini do stejné složky a vše funguje. Použitý php.ini soubor lze ověřit ve výpisu phpinfo(); v řádku Loaded Configuration File.

Výpis PHPinfo

Nastavení virtual hostů

Popsáno je pouze nastavení s různými verzemi PHP, základem je znalost dřívějšího článku o nastavení virtual hostů. Pokud na virtual hostu má fungovat stejná verze jako je defaultní, viz výše, konfigurace je shodná, jako v případě mod_php. Pokud ale pod virtual hostem má v základu běžet jiná verze PHP, je potřeba vytvořit nový FcgidWrapper:

<VirtualHost *:80>
    DocumentRoot "C:/xampp/htdocs/"
    ServerName localhost7
    
    <Directory "C:/xampp/htdocs/"> 
        <Files ~ "\.php$"> 
            FcgidWrapper "c:/web/xampp/php7.1/php-cgi.exe" .php 
        </Files> 
    </Directory>  
</VirtualHost>

Zde jde vidět, proč je nutné mít FcgidMaxProcesses nastavenou na vyšší hodnotu.

TIP pro rychlé přepínání

V případě, že bude potřeba se někdy vracet k mod_php namísto FastCGI, je vhodné zakomentované nastavení výše i nové nastavení vložit do nových souborů a použít Include. Poté stačí jen přehozením komentářů vložit jeden nebo druhý soubor.

# Část souboru C:\xampp\apache\conf\extra\httpd-xampp.conf

# PHP-Module setup
# Include conf/extra/mod_php.conf

# PHP-FastCGI setup
Include conf/extra/mod_fcgi.conf

MAMP PRO

Automatizace s MAMP

Pro ještě línější lidi, než jsem já, mám dobrou zprávu. Program MAMP dokáže vše výše popsané nastavovat a řešit na pár kliknutí. Svého času byl pouze pro MacOX, ale již existuje i Windows verze. Kromě jiného dokáže i nastavit virtual hosty včetně zápisu do hosts souboru. To vše popsané ale umí pouze MAMP PRO, který už je placený. Proto já osobně nadále budu preferovat detailnější ruční nastavování.


S osobními zkušenostmi se můžete podělit v komentářích. Pro napsání článků jsem použil zdroje: dionysopoulos.me, commaster.net a dokumentaci php.net.

Přidat komentář

Položky označené * jsou povinné. Email nebude zveřejněn

Komentáře

Je možné v MAMPu PRO docílit běhu starší verze např. 5.2.7, která nepodporuje Apache 2.4, ale pouze Apache 2.2?

MAMP nepoužívám, a už vůbec ne MAMP PRO, takže opravdu nevím a neporadím. Je mi líto

Dal by se použít tento postup i pro Linux? Jak moc je to rizikové provádět to přímo na vývojovém prostředí?

Tak na vývojovém prostředí si můžeš asi dělat co chceš. Ale upřímně, jak to zprovoznit pod Linuxem nevím. Nejsem tak zběhlý na linuxu. Předpokládám, že postup bude velmi podobný.

Díky Pavle, šlo mi o to, zda je to bezpečné v souvislosti s původní konfiguraci (používám taky xampp, respektive lamp). Přece jen mám trochu strach ohledně konfigurace a stávajících projektu.

Tak to je v pohodě. Pokud nezměníš nastavení PHP tak to bude fungovat stále stejně. Nezaznamenal jsem vůbec žádnou změnu