Навіщо потрібно кілька версій PHP
На хостингу з кількома сайтами часто потрібні різні версії PHP: один сайт на WordPress вимагає PHP 8.1+, інший — старий Magento 1 працює лише на PHP 7.4. Через репозиторій ondrej/php можна тримати кілька версій одночасно.
Встановлення репозиторію ondrej/php (Ubuntu/Debian)
sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt updateВстановлення кількох версій PHP
# PHP 7.4
sudo apt install php7.4-fpm php7.4-cli php7.4-mysql php7.4-curl \
php7.4-mbstring php7.4-xml php7.4-zip php7.4-gd
# PHP 8.1
sudo apt install php8.1-fpm php8.1-cli php8.1-mysql php8.1-curl \
php8.1-mbstring php8.1-xml php8.1-zip php8.1-gd
# PHP 8.2
sudo apt install php8.2-fpm php8.2-cli php8.2-mysql php8.2-curl \
php8.2-mbstring php8.2-xml php8.2-zip php8.2-gdПеревірка запущених PHP-FPM
systemctl status php7.4-fpm php8.1-fpm php8.2-fpm
# Список сокетів
ls /run/php/
# php7.4-fpm.sock php8.1-fpm.sock php8.2-fpm.sockНалаштування Nginx: різні версії для різних сайтів
# Сайт 1 — PHP 8.2
server {
server_name newsite.com;
root /var/www/newsite;
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
# Сайт 2 — PHP 7.4 (старий сайт)
server {
server_name oldsite.com;
root /var/www/oldsite;
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}Вибір версії PHP CLI за замовчуванням
# Показати поточну версію
php --version
# Список доступних версій
update-alternatives --list php
# Змінити версію за замовчуванням
sudo update-alternatives --set php /usr/bin/php8.2
# Інтерактивний вибір
sudo update-alternatives --config phpЗміна версії PHP для cPanel (через .htaccess)
# У .htaccess сайту
AddHandler application/x-httpd-php82 .php
# або через пул PHP-FPM — задається в налаштуваннях хостингуphp.ini для PHP 8.2 не впливає на PHP 7.4.Реальні помилки при змішуванні версій
Сокет не знайдено
connect() to unix:/run/php/php7.4-fpm.sock failed (2: No such file or directory), client: 1.2.3.4, server: oldsite.com, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.4-fpm.sock:"Це помилка Nginx, не PHP: вказаний у vhost сокет не існує. Або служба php7.4-fpm не запущена, або у власному конфігу пулу сокет називається інакше — перевіряйте обидва місця, а не лише Nginx.
Ту саму за змістом помилку видає й Apache з mod_proxy_fcgi, лише формулювання інше — AH01079: failed to make connection to backend. Суть одна: вебсервер звертається не до того сокета або служба не запущена.
Синтаксис не підтримується старою версією
PHP Parse error: syntax error, unexpected identifier "string", expecting "{" in /var/www/html/app/Status.php on line 5Типова причина — у коді використовується enum (з'явився в PHP 8.1), а сайт помилково обслуговується пулом PHP 7.4. Помилка синтаксису без жодної підказки про версію збиває з пантелику: код виглядає абсолютно робочим, якщо відкрити його на своїй машині з PHP 8.2.
Коли кілька версій — джерело проблем
- Розширення встановлено для однієї версії, але не для іншої:
php8.2-imagickстоїть, аphp7.4-imagick— ні, і старий сайт падає з «Class Imagick not found» без видимої причини на перший погляд. - Кожна версія PHP-FPM тримає власний пул воркерів і власний OPcache — за малого обсягу RAM три версії PHP з'їдають пам'яті як три незалежні сервери.
- Cron-завдання, запущені через звичайний
php, використовують версію за замовчуванням зupdate-alternatives, а не ту, що налаштована в пулі FPM для сайту — легко отримати розбіжність між вебом і cron.
Перевірка результату
# Чи всі демони реально запущені
systemctl status php7.4-fpm php8.1-fpm php8.2-fpm --no-pager
# Яка версія обслуговує конкретний сайт
curl -sI https://newsite.com | grep -i x-powered-by
# Синтаксис конфігурації Nginx коректний
nginx -tЯкщо systemctl status показує active (running), але сайт усе одно віддає 502 — перевірте власника та права на сам файл сокета: PHP-FPM і Nginx повинні мати доступ до того самого шляху зі збіжними правами групи.
Ще один спосіб пересвідчитися, що запит обслуговує саме та версія, яка потрібна, — тимчасово додати в код сайту echo phpversion(); і звірити з виводом у браузері. Швидше за повноцінний phpinfo(), але для точкової перевірки достатньо.
Видаляйте такий налагоджувальний рядок одразу після перевірки — забутий echo phpversion(); на бойовій сторінці видає версію PHP будь-кому, включно з ботами, які шукають відомі вразливості під конкретні релізи.