Зачем нужно несколько версий 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 кому угодно, включая ботов, которые ищут известные уязвимости под конкретные релизы.