Обновление версии PHP в существующем приложении — это не просто смена образа контейнера или конфигурации сервера. Среда выполнения взаимодействует с кодом, расширениями, библиотеками Composer и процессами, выполняющими запланированные задачи или фоновые задания. Изменение может затронуть любой из этих компонентов, даже если во время ручной проверки приложение, на первый взгляд, работает нормально.
Снизить неопределённость можно, если рассматривать обновление как изменение совместимости: инвентаризировать всё, что выполняется, найти несовместимости, проверить репрезентативные сценарии и заранее определить, как решать, продолжать ли развёртывание или откатывать его. Цель — выделить работу, необходимую для новой среды выполнения, а не превращать обновление в переписывание продукта.
Среда выполнения — часть совместимости приложения

Версия PHP определяет, какой синтаксис поддерживает интерпретатор и как ведут себя некоторые функции и типы. Она также определяет, какие версии расширений и зависимостей можно установить. Поэтому тот факт, что код работал в текущем окружении, ещё не доказывает, что он будет работать в новом: могут измениться функция, интерфейс, поведение типов или доступность расширения.
Следует различать три области: код приложения, сторонние зависимости и конфигурацию окружения. Если менять все три одновременно, причину сбоя будет сложнее установить. При планировании обновления эти изменения по возможности разделяют и явно фиксируют, какой компонент потребовал каждую корректировку.
Инвентаризируйте среду выполнения, зависимости и процессы
Прежде чем что-либо менять, зафиксируйте фактическое окружение выполнения, а не только то, которое описано в конфигурационном файле проекта. Проверьте версию PHP в контейнерах или на серверах, которые обрабатывают запросы, а также в окружениях, где выполняются запланированные задачи, обработчики очередей и команды обслуживания. Для этих процессов могут использоваться другие образы, переменные или расширения.
- Среда выполнения и расширения: определите, какие расширения включены, зафиксируйте их версии, если это важно, а также системные библиотеки, от которых они зависят. Сравните требования продакшена, CI и разработки.
- Зависимости Composer: проверьте
composer.json, файл блокировки зависимостей и ограничения версий PHP, объявленные пакетами. Проверьте также инструменты разработки, например анализаторы и средства запуска тестов. - Конфигурация: составьте перечень значений
php.ini, ограничений памяти и времени, настроек обработки ошибок и параметров конкретного сервера. Новая среда выполнения не гарантирует, что важные настройки будут сохранены. - Работа вне веб-запросов: включите в проверку cron, очереди, консольные команды, импорт, экспорт и длительные задачи. Успешная работа веб-сценария автоматически не подтверждает корректность этих процессов.
- Интеграции и данные: зафиксируйте внешние сервисы, форматы обмена данными и операции записи в базы данных или хранилища. Это поможет определить, какие операции требуют особого внимания при откате.
Инвентаризацию можно вести в списке в репозитории или в эксплуатационной документации — главное, чтобы она позволяла сравнивать окружения и выявлять расхождения. Частый признак неполной инвентаризации: CI проходит, но после развёртывания завершается с ошибкой обработчик очереди или запланированная задача.
Ищите несовместимости по нескольким сигналам
Начните с автоматизированных инструментов: проверьте ограничения платформы Composer и выполните проверку зависимостей с целевой версией PHP. Конфликт при разрешении зависимостей означает, что какой-либо пакет, в том числе инструмент разработки, не декларирует совместимость с этой платформой. Не следует принудительно устанавливать зависимости, скрывая конфликт, пока не выяснено, какое требование при этом обходится.
Дополните этот анализ доступными в проекте инструментами статического анализа и проверками стиля или совместимости. Они могут выявить подозрительные конструкции, устаревшие API или шаблоны, требующие проверки, но сами по себе не доказывают, что приложение целиком работает. Точно так же успешный анализ не заменяет фактический запуск: некоторые ошибки проявляются только при прохождении редко используемой ветки кода или загрузке расширения.
Запускайте тесты с целевой средой выполнения и расширениями, которые планируется использовать в продакшене. Если набор тестов ограничен, добавьте ручные или автоматизированные проверки наиболее важных сценариев: аутентификации, операций записи, приёма платежей, если они предусмотрены, генерации документов и основных интеграций. Фиксируйте также ошибки и предупреждения: изменение, превращающее предупреждение в исключение, может прервать выполнение сценария до того, как это обнаружит набор тестов.
Выстройте работу так, чтобы изолировать риск
Практичная последовательность: сначала подтвердить целевой образ или конфигурацию и набор расширений, затем разрешить ограничения зависимостей и в последнюю очередь исправить код и настройки, мешающие запуску тестов. Оставляйте каждую группу изменений удобной для проверки. Если необходимо обновить библиотеку, задокументируйте, какое требование вызвало это изменение, и проверьте в приложении области, где она используется.
Не обновляйте без разбора все зависимости в рамках одного шага. Масштабное обновление может быть необходимо, но при регрессии оно увеличивает число возможных причин. Если разделить изменения нельзя, зафиксируйте, какие пакеты изменились, и добавьте тесты для зависящих от них функций. Также убедитесь, что файл блокировки зависимостей одинаково формируется и устанавливается в CI и продакшене.
Конфигурация должна соответствовать целевому окружению. Проверка с расширением, установленным только в CI, даёт ложный сигнал; то же относится к ситуации, когда фоновые задачи продолжают выполняться на прежней среде выполнения. Прежде чем связывать результат с кодом, сравните образы, команды запуска, переменные и конфигурацию тестового и производственного окружений.
Проверьте работу в репрезентативном окружении и определите критерии выхода
CI должен выполнять установку, анализ и тесты с целевой средой выполнения, а не только с текущей. Добавляйте отдельные задания для других версий среды выполнения только в том случае, если приложение должно поддерживать несколько версий: тогда каждую поддерживаемую комбинацию необходимо проверять явно. Матрица CI показывает, какие комбинации тестируются, но автоматически не учитывает особенности продакшена.
Используйте предпродакшен-окружение, достаточно похожее на реальное, чтобы проверить запуск, критичные сценарии, интеграции, очереди и запланированные задачи. Сравните журналы, ошибки, время отклика и потребление ресурсов до и после изменения. Заранее определите, какое поведение остановит развёртывание, кто принимает это решение и как долго будет вестись наблюдение за системой. Пороговые значения должны опираться на потребности приложения и доступные сигналы, а не на универсальные значения.
Полезные критерии выхода: воспроизводимая установка, успешное прохождение согласованного набора тестов, проверка критичных сценариев, отсутствие необъяснённых новых ошибок и возможность выполнять фоновые процессы. Задокументируйте известные исключения и укажите ответственных за них. Формулировки «тесты проходят» недостаточно, если набор не охватывает важную интеграцию или команда не знает, за какой метрикой следить.
Развёртывайте с учётом совместимости отката с данными
Если архитектура и платформа это позволяют, развёртывайте новую среду выполнения поэтапно: сначала в контролируемом окружении, затем — для части трафика или вычислительной мощности. Поэтапное развёртывание — стратегия развёртывания, а не раскрытие информации. Распределять запросы между версиями удаётся не всегда — например, при наличии процессов с состоянием или различий во внутреннем протоколе. В таком случае спланируйте согласованный переход и явно проверьте отправителей и получателей сообщений.
Перед развёртыванием убедитесь, что при сбое можно снова запустить прежнюю версию кода. Откат — это не просто возврат к прежнему образу: миграция базы данных, новый формат сообщения или несовместимая запись могут помешать прежней среде выполнения читать данные, созданные новой. По возможности вносите изменения схемы поэтапно, сохраняя совместимость: сначала расширьте схему, затем разверните код, способный работать с обоими вариантами, и удалите старый вариант, когда он больше не будет нужен потребителям. Для каждого необратимого шага определите отдельный способ восстановления и условие остановки.
Во время развёртывания отслеживайте ошибки приложения и среды выполнения, сбои обработчиков очередей, задержки очередей, запланированные задачи и важные бизнес-сигналы. Если сработал критерий отката, остановите дальнейшее распространение изменения и следуйте проверенной процедуре. Сохраните журналы, необходимые для определения причины: откат без диагностики может привести к повторению того же сбоя при следующей попытке.
Контрольный список готовности

- Определены ли среда выполнения и расширения для всех окружений и процессов?
- Проверены ли ограничения Composer и инструменты разработки?
- Запускаются ли анализ и тесты с целевой конфигурацией?
- Проверены ли критичные сценарии, интеграции, очереди и запланированные задачи?
- Известны ли различия между CI, предпродакшеном и продакшеном?
- Определены ли эксплуатационные сигналы, ответственные и чёткие критерии продолжения или остановки?
- Может ли прежний код работать с данными и сообщениями, которые будет создавать новый?
- Проверен ли откат и известно ли, какие изменения нельзя отменить автоматически?
Решение обновить версию PHP в существующем приложении будет более обоснованным, если команда может ответить на эти вопросы, опираясь на факты. Если не хватает тестов или инвентаризации, следующим шагом не обязательно должно быть переписывание приложения: сначала можно устранить эти пробелы и сократить масштаб изменений. Тогда потенциальные сбои обнаружатся до того, как затронут пользователей, а для каждого решения о развёртывании будет установлен проверяемый критерий.



