Обновление PHP на сервере: как не сломать сайт

Обновление PHP — это как хирургическая операция на живом сердце. Я за 10 лет практики видел десятки сайтов, которые "умирали" после неосторожного апгрейда версии. И знаете что? В 90% случаев это можно было предотвратить.

Зачем вообще обновлять PHP

Честно говоря, многие разработчики сидят на старых версиях PHP годами. У меня был клиент, который до 2023 года работал на PHP 5.6 — представляете? Сайт тормозил, уязвимости торчали как гвозди из доски, но "работает же, зачем трогать".

А потом случилось то, что должно было случиться — сайт взломали через известную уязвимость в старой версии интерпретатора. Пришлось не только обновлять PHP до 8.1, но и восстанавливать весь проект с нуля. Куда проще было бы сделать это планово.

PHP 8.3 работает в среднем на 30-40% быстрее PHP 7.4. На одном из моих проектов (интернет-магазин с 50к товаров) переход с 7.4 на 8.2 дал прирост скорости почти в 2 раза. PageSpeed Insights показал рост с 65 до 89 баллов только за счёт обновления интерпретатора.

ℹ️
Важный факт: Поддержка PHP 7.4 официально закончилась в ноябре 2022 года. PHP 8.0 — в ноябре 2023. Если ваш сайт работает на этих версиях, вы в зоне риска.

Но главная причина обновления — безопасность. Каждая новая версия PHP закрывает десятки уязвимостей. Когда поддержка версии заканчивается, патчи безопасности больше не выходят. Ваш сайт становится лёгкой мишенью для атак.

Проверка совместимости перед обновлением

Самая частая ошибка — сразу переключить версию PHP на продакшене. Я так делал один раз в начале карьеры. Результат: белый экран смерти и 6 часов восстановления в выходной день. Больше никогда.

Первым делом проверяю текущую версию PHP на сервере:

php -v
# или через веб-интерфейс
echo phpinfo();

Затем анализирую код проекта на совместимость. Для этого использую несколько инструментов:

PHP Compatibility Checker — плагин для WordPress, который сканирует весь код и выдаёт отчёт о проблемах. Для Битрикс такого готового решения нет, поэтому приходится проверять вручную или писать скрипты.

PHPStan — статический анализатор кода. Запускаю его на максимальном уровне строгости:

composer require --dev phpstan/phpstan
./vendor/bin/phpstan analyse src --level=9

На практике больше всего проблем возникает с:

У одного клиента с большим порталом на Битрикс при переходе с PHP 7.4 на 8.1 вылезло 47 критических ошибок. Половина из них была связана с устаревшими функциями в кастомных модулях, написанных ещё в 2018 году.

⚠️
Критично: Никогда не обновляйте PHP на продакшене без тестирования. Даже если анализаторы кода не нашли проблем, реальное поведение может отличаться.

Создание бэкапа перед обновлением

Перед любым обновлением я делаю полный бэкап. Не только файлов, но и базы данных. Причём проверяю, что бэкап действительно восстанавливается — у меня был случай, когда дамп базы оказался битым из-за неправильной кодировки.

Для файлов использую rsync или tar:

# Архивирование всего сайта
tar -czf site_backup_$(date +%Y%m%d).tar.gz /var/www/html/

# Или синхронизация в отдельную папку
rsync -av --exclude='cache' /var/www/html/ /backups/site_$(date +%Y%m%d)/

Для базы данных — mysqldump с правильными параметрами:

# Полный дамп с сохранением кодировки и структуры
mysqldump --single-transaction --routines --triggers \
  --default-character-set=utf8mb4 -u user -p database_name \
  > db_backup_$(date +%Y%m%d).sql

# Проверка целостности дампа
mysql -u user -p -e "SET autocommit=0; SOURCE db_backup_$(date +%Y%m%d).sql; ROLLBACK;"

Обязательно тестирую восстановление на копии сайта. Недавно спас клиента — оказалось, что автоматический бэкап хостинга не включал кастомные конфиги nginx, которые были критичны для работы сайта.

Подробнее о правильном создании бэкапов я писал в отдельной статье — там есть готовые скрипты и чек-листы.

Тестирование на копии сайта

Никогда не обновляю PHP сразу на продакшене. Всегда создаю тестовую копию сайта и экспериментирую на ней. Это правило №1, которое сэкономило мне сотни часов и нервных клеток.

Обычно разворачиваю копию на поддомене test.example.com или на локальном сервере. Для быстрого развёртывания использую Docker:

# docker-compose.yml для тестирования
version: '3.8'
services:
  web:
    image: php:8.2-apache
    ports:
      - "8080:80"
    volumes:
      - ./site:/var/www/html
    environment:
      - PHP_VERSION=8.2
  
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: testdb
    volumes:
      - ./db_backup.sql:/docker-entrypoint-initdb.d/backup.sql

На тестовой копии прогоняю весь функционал сайта:

У одного клиента тестирование выявило проблему с модулем оплаты — после обновления до PHP 8.1 перестали работать уведомления от платёжной системы из-за изменений в обработке POST-запросов. На продакшене это привело бы к потере денег.

Особое внимание уделяю логам ошибок. Включаю детальное логирование:

# В php.ini
error_reporting = E_ALL
log_errors = On
error_log = /var/log/php_errors.log
display_errors = Off  # На продакшене обязательно Off!
💡
Лайфхак: Настройте мониторинг логов ошибок в реальном времени. Я использую tail -f /var/log/php_errors.log во время тестирования — так сразу видно все проблемы.

Поэтапное обновление PHP

Я никогда не прыгаю сразу с PHP 7.4 на 8.3. Всегда делаю промежуточные шаги: 7.4 → 8.0 → 8.1 → 8.2 → 8.3. Да, дольше, но гораздо безопаснее.

Каждый мажорный релиз PHP вносит breaking changes. В PHP 8.0 изменилось поведение функций сравнения, в 8.1 появились новые уровни ошибок, в 8.2 — устарели динамические свойства классов.

Процесс обновления на Ubuntu/Debian:

# Добавляем репозиторий Ondrej Sury (актуальные версии PHP)
sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:ondrej/php

# Устанавливаем нужную версию PHP
sudo apt update
sudo apt install php8.2 php8.2-fpm php8.2-mysql php8.2-mbstring \
  php8.2-xml php8.2-gd php8.2-curl php8.2-zip

# Переключаем версию по умолчанию
sudo update-alternatives --set php /usr/bin/php8.2

Для nginx нужно обновить конфигурацию:

# В конфиге виртуального хоста
location ~ \.php$ {
    fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;  # Обновляем сокет
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

На одном проекте (крупный корпоративный портал) переход занял 3 месяца. Сначала обновили с 7.4 до 8.0, месяц тестировали, потом до 8.1, снова тестировали. В итоге — ноль проблем на продакшене.

После каждого шага обновления проверяю:

Типичные ошибки при обновлении и их решение

За годы практики я собрал коллекцию самых частых проблем. Вот топ-5 ошибок, с которыми сталкиваются почти все:

1. Fatal error: Uncaught Error: Call to undefined function mysql_connect()

Функции mysql_* удалены в PHP 7.0. Нужно переписать на mysqli или PDO:

# Старый код
$connection = mysql_connect($host, $user, $password);
mysql_select_db($database, $connection);

# Новый код
$connection = new mysqli($host, $user, $password, $database);
if ($connection->connect_error) {
    die('Connection failed: ' . $connection->connect_error);
}

2. Warning: count(): Parameter must be an array or an object that implements Countable

В PHP 7.2+ функция count() стала строже к типам данных:

# Проблемный код
$result = someFunction(); // может вернуть null
if (count($result) > 0) {
    // ...
}

# Исправленный код
$result = someFunction();
if (is_array($result) && count($result) > 0) {
    // ...
}

3. Parse error: syntax error, unexpected 'match' (T_MATCH)

В PHP 8.0 появились новые зарезервированные слова. Если у вас есть переменные или функции с именами match, readonly — переименуйте их.

4. Deprecated: Creation of dynamic property

PHP 8.2 начал ругаться на создание свойств объектов "на лету". Решение — объявить свойства в классе или использовать магические методы:

class MyClass {
    public $dynamicProperty; // Объявляем заранее
    
    // Или используем магические методы
    public function __set($name, $value) {
        $this->$name = $value;
    }
}

5. Проблемы с кодировкой после обновления

Иногда после обновления PHP ломается отображение русских символов. Проверьте настройки в php.ini:

default_charset = "UTF-8"
mbstring.internal_encoding = UTF-8
mbstring.http_output = UTF-8

У одного клиента после обновления до PHP 8.1 перестал работать модуль интеграции с 1С — оказалось, что код использовал устаревший способ обработки XML. Пришлось переписать парсер с использованием современного DOMDocument.

⚠️
Важно: Многие ошибки проявляются не сразу, а только при определённых условиях. Обязательно тестируйте все сценарии использования сайта.

Обновление CMS и плагинов

Обновление PHP часто тянет за собой обновление CMS и всех плагинов. Это логично — разработчики тоже адаптируют свой код под новые версии интерпретатора.

WordPress

WordPress довольно лояльно относится к новым версиям PHP. Но плагины — другое дело. У меня был случай, когда после обновления до PHP 8.1 перестал работать плагин WooCommerce — старая версия не поддерживала новый синтаксис.

Перед обновлением PHP проверяю совместимость всех плагинов:

# Список установленных плагинов
wp plugin list --allow-root

# Проверка обновлений
wp plugin update --all --dry-run --allow-root

Подробнее об оптимизации WordPress я писал отдельно — там есть нюансы работы с разными версиями PHP.

Битрикс

Битрикс более консервативен в плане поддержки новых версий PHP. Версия 22.0 официально поддерживает PHP до 8.1, более новые версии могут работать, но без гарантий.

Перед обновлением обязательно читаю release notes и проверяю матрицу совместимости на сайте 1С-Битрикс. У одного клиента обновление до PHP 8.2 сломало модуль "Интернет-магазин" — пришлось откатываться до 8.1.

Процесс обновления Битрикс описан в отдельной статье — там есть все нюансы и подводные камни.

Laravel

С Laravel проще всего — фреймворк быстро адаптируется к новым версиям PHP. Laravel 10 поддерживает PHP 8.1+, Laravel 11 требует PHP 8.2+.

Главное — обновить зависимости через Composer:

composer update
composer audit  # Проверка уязвимостей

О выборе Laravel для бизнес-проектов я подробно писал в этой статье.

Настройка php.ini после обновления

После установки новой версии PHP обязательно проверяю и настраиваю php.ini. Дефолтные настройки редко подходят для продакшен-серверов.

Мои стандартные настройки для веб-серверов:

# Память и время выполнения
memory_limit = 256M                # Для Битрикс лучше 512M
max_execution_time = 300           # 5 минут для тяжёлых операций
max_input_time = 300

# Загрузка файлов
upload_max_filesize = 64M
post_max_size = 64M
max_file_uploads = 20

# Сессии
session.gc_maxlifetime = 3600      # 1 час
session.cookie_httponly = On
session.cookie_secure = On         # Только для HTTPS

# Безопасность
expose_php = Off                   # Скрываем версию PHP
allow_url_fopen = Off             # Запрещаем удалённые include
allow_url_include = Off

# Кеширование опкодов (встроенный OPcache)
opcache.enable = 1
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.validate_timestamps = 0    # На продакшене отключаем

Для Битрикс добавляю специфичные настройки:

# Дополнительно для Битрикс
mbstring.func_overload = 0         # Обязательно!
mbstring.internal_encoding = UTF-8
short_open_tag = On                # Битрикс использует короткие теги

У одного клиента после обновления сайт стал тормозить из-за того, что OPcache был отключен. Включение дало прирост скорости в 3 раза — с 2 секунд до 0.7 секунды загрузки главной страницы.

Обязательно перезапускаю PHP-FPM после изменения конфигурации:

sudo systemctl restart php8.2-fpm
sudo systemctl status php8.2-fpm  # Проверяем статус

Мониторинг после обновления

Обновление — это только половина дела. Вторая половина — убедиться, что всё работает стабильно. Я мониторю сайт минимум неделю после обновления PHP.

Что отслеживаю в первую очередь:

Логи ошибок

Настраиваю ротацию логов и слежу за новыми ошибками:

# Мониторинг логов в реальном времени
tail -f /var/log/php_errors.log | grep -i error

# Анализ ошибок за день
grep "$(date '+%d-%b-%Y')" /var/log/php_errors.log | sort | uniq -c | sort -nr

Производительность

Использую простые скрипты для замера времени отклика:

#!/bin/bash
# monitor_site.sh
for i in {1..10}; do
    time curl -s -o /dev/null -w "%{time_total}\n" https://example.com/
    sleep 10
done

Или более продвинутые инструменты типа New Relic, если проект позволяет.

Потребление ресурсов

Слежу за нагрузкой на сервер — иногда новая версия PHP может увеличить потребление памяти:

# Мониторинг процессов PHP
watch -n 5 "ps aux | grep php-fpm | grep -v grep"

# Проверка памяти
free -m
cat /proc/meminfo | grep -i mem

У одного клиента после обновления до PHP 8.0 потребление памяти выросло на 40%. Оказалось, что новая версия более требовательна к ресурсам для их конкретного кода. Пришлось увеличить лимиты и оптимизировать некоторые запросы.

Пользовательские сценарии

Настраиваю автоматические тесты ключевых функций сайта. Для интернет-магазинов — тестирую процесс покупки, для корпоративных сайтов — отправку форм и загрузку файлов.

💡
Совет: Используйте uptime-мониторинг типа UptimeRobot или Pingdom. Они сразу уведомят, если сайт перестанет отвечать.

Что делать, если что-то пошло не так

Даже при самой тщательной подготовке иногда что-то идёт не по плану. У меня был случай — после обновления до PHP 8.1 сайт работал, но периодически выдавал 500 ошибку при определённых действиях пользователей. Проблема проявилась только через несколько дней.

План быстрого отката

Всегда держу наготове план отката к предыдущей версии PHP:

# Быстрый откат версии PHP на Ubuntu
sudo update-alternatives --set php /usr/bin/php7.4

# Откат конфигурации nginx
sudo cp /etc/nginx/sites-available/site.conf.backup \
       /etc/nginx/sites-available/site.conf
sudo systemctl reload nginx

# Откат PHP-FPM
sudo systemctl stop php8.2-fpm
sudo systemctl start php7.4-fpm

Восстановление из бэкапа

Если проблемы критичные, восстанавливаю весь сайт из бэкапа:

# Восстановление файлов
tar -xzf site_backup_20260115.tar.gz -C /var/www/html/

# Восстановление базы данных
mysql -u user -p database_name < db_backup_20260115.sql

У того клиента с периодическими 500 ошибками мы в итоге откатились к PHP 8.0 и потратили ещё месяц на поиск и исправление проблемного кода. Оказалось, что ошибка была в кастомном модуле, который некорректно обрабатывал новый тип данных.

Поиск причин проблем

Когда что-то ломается, я действую по алгоритму:

  1. Проверяю логи ошибок PHP
  2. Анализирую логи веб-сервера (nginx/Apache)
  3. Смотрю системные логи (dmesg, /var/log/syslog)
  4. Тестирую функционал на тестовой копии
  5. Ищу в Google/Stack Overflow похожие проблемы

Больше о диагностике проблем с сайтами я писал в статье "Как исправить ошибки на сайте".

Когда обращаться к специалистам

Если проблема критичная и вы не можете её решить самостоятельно в течение нескольких часов — лучше обратиться к специалистам. Время простоя сайта может стоить гораздо дороже, чем услуги разработчика.

На моей практике клиенты часто пытаются решить проблемы самостоятельно и только усугубляют ситуацию. Недавно пришёл клиент, который сам пытался обновить PHP и в результате сломал не только сайт, но и всю конфигурацию сервера. Восстановление заняло целый день.

Рекомендации по планированию обновлений

Обновление PHP — это не разовая акция, а регулярный процесс. У меня есть календарь обновлений для всех клиентских проектов. Планирую их заранее и провожу в периоды минимальной активности пользователей.

График поддержки версий PHP

Каждая версия PHP поддерживается 3 года: 2 года активной поддержки + 1 год только исправления безопасности. После этого — никаких обновлений. Вот актуальный график:

Оптимальная стратегия обновлений

Я рекомендую обновлять PHP каждые 1-2 года, не дожидаясь окончания поддержки. Оптимальная схема:

  1. Используем стабильную версию N-1 (сейчас это PHP 8.2)
  2. Тестируем новую версию N на копии проекта
  3. Планируем обновление за 3-6 месяцев до окончания поддержки текущей версии

Выбор времени для обновления

Лучшее время для обновлений:

У одного клиента (интернет-магазин детских товаров) мы планируем все обновления на период с 15 января по 15 февраля — после новогодних продаж и до начала весенней активности.

Документирование изменений

Веду документацию по всем обновлениям: что обновлялось, какие проблемы возникли, как решались. Это помогает при планировании следующих обновлений.

Пример записи в журнале обновлений:

Дата: 15.01.2026
Проект: shop.example.com
Обновление: PHP 7.4 → 8.1
Время: 02:00-04:30 (2.5 часа)
Проблемы: 
- Ошибка в модуле оплаты (исправлено заменой deprecated функции)
- Увеличение потребления памяти на 15%
Результат: Успешно, прирост скорости +35%

Если у вас нет времени или экспертизы для самостоятельного обновления, всегда можно воспользоваться услугами поддержки сайтов — мы регулярно обновляем PHP на десятках проектов и знаем все подводные камни.

Обновление PHP — это инвестиция в будущее вашего проекта. Да, требует времени и внимания, но результат того стоит: быстрее работа, выше безопасность, лучше SEO-показатели. Главное — не торопиться и всё тщательно тестировать.

Боитесь обновлять PHP из-за возможных проблем с сайтом?

Наши специалисты проведут безопасное обновление PHP с полным тестированием и гарантией работоспособности.

П
Павел
Веб-разработчик · 10+ лет опыта · Bitrix, WordPress, Laravel

Читайте также

Бэкапы сайта: как делать правильно и не терять данные Переезд с WordPress на Битрикс: пошаговый план Почему сайт не индексируется в Яндекс и Google