
Обновление legacy PHP проекта: пошаговый план
Обновление legacy PHP-проекта безопасно проходит поэтапно: аудит, тесты, статанализ, Rector, переход по версиям и релиз с возможностью отката.
Обновление legacy PHP-проекта: как перейти на актуальную версию без простоев
Legacy PHP-проект обновляют поэтапно: сначала аудит и тесты, затем статический анализ и автоматический рефакторинг. После этого переходят по версиям PHP по одной за раз и выкатывают релиз с быстрым откатом.
Старый PHP-проект редко выглядит как катастрофа. Он годами приносит деньги, а потом выясняется, что хостинг отказывается поддерживать PHP 5.6, библиотеки не ставятся, а любая правка занимает неделю. Ниже разобрано, как провести обновление предсказуемо: что проверить заранее, в каком порядке менять версии, какие инструменты взять и как не навредить работающему бизнесу.
Почему откладывать обновление опасно
Версии PHP 7.4 и старше больше не получают исправлений безопасности. Любая найденная уязвимость остаётся в вашем проекте навсегда. Для интернет-магазина, личного кабинета или CRM это прямой риск утечки данных и простоя.
Есть и менее заметные последствия. Современные библиотеки и SDK платёжных систем, служб доставки и маркетплейсов всё чаще требуют PHP 8 и выше. Разработчиков, которые хотят работать с кодом на PHP 5.x, становится меньше, а их услуги дорожают. Каждый год промедления увеличивает объём работы: накапливаются удалённые функции, изменённое поведение и несовместимые пакеты.
Чем дольше проект стоит на старой версии, тем дороже обходится переход. Обновление, разбитое на небольшие шаги, всегда дешевле одного аврального «большого взрыва» перед отключением хостинга.
Что даёт обновление legacy PHP-проекта
- 01
Закрытые уязвимости и возвращённая поддержка безопасности от сообщества и хостинг-провайдеров
- 02
Прирост производительности: PHP 7 заметно быстрее PHP 5.6, а PHP 8 добавляет JIT и дальнейшие оптимизации
- 03
Современный синтаксис: типы, enum, match, именованные аргументы, readonly-свойства
- 04
Возможность обновить фреймворк и библиотеки, подключить современные SDK и API
- 05
Более простой найм и онбординг: разработчики охотнее работают с актуальным стеком
- 06
Основа для дальнейшего рефакторинга, автотестов и CI/CD
Этап нулевой: инвентаризация и подготовка
Прежде чем менять версию, нужно понять, с чем вы имеете дело. Выпишите текущую версию PHP, список подключённых расширений, настройки php.ini, cron-задачи и очереди. Проверьте, что версии зависимостей зафиксированы в composer.lock. Если проект подключает библиотеки вручную, копируя папки в репозиторий, это первая вещь, которую стоит привести в порядок.
Второй шаг — воспроизводимое окружение. Поднимите копию проекта в Docker с той же версией PHP, что и на продакшене, и с копией обезличенной базы данных. Если проект запускается локально и на стейджинге, вы можете безопасно экспериментировать. Заодно выясните, какие страницы и разделы реально используются: статистика из Яндекс Метрики или Google Analytics подскажет, какие сценарии критичны, а какой код давно мёртв и его можно не переносить.
Пошаговый план обновления
- 01
Зафиксируйте текущее состояние: версия PHP, расширения, composer.lock, конфигурации, cron-задачи. Разверните идентичную копию проекта в Docker.
- 02
Проведите инвентаризацию зависимостей: команды composer outdated и composer audit покажут устаревшие пакеты и известные уязвимости. Составьте список заброшенных библиотек, которые придётся заменить.
- 03
Создайте тестовую сетку: напишите характеризационные тесты на критичные сценарии — авторизацию, корзину, оплату, формы, импорт и экспорт данных.
- 04
Подключите статический анализ: PHPStan или Psalm и стандарт PHPCompatibility для PHP_CodeSniffer. Получите полный список проблем под целевую версию.
- 05
Автоматизируйте правки: примените Rector с наборами правил для нужной версии PHP и PHP CS Fixer для единого стиля. Проверяйте результат по диффам, а не вслепую.
- 06
Переходите по одной версии за раз: после каждого шага запускайте тесты, смотрите логи на ошибки и Deprecated, прогоняйте стейджинг.
- 07
Выкатывайте постепенно: канареечный релиз или blue-green деплой, мониторинг ошибок и заранее подготовленный план отката.
Тесты как страховочная сетка
Legacy-код опасен тем, что никто не помнит, как он должен работать. Поэтому до обновления нужно зафиксировать текущее поведение. Такие тесты называют характеризационными: они не проверяют, правильно ли работает система, а лишь запоминают, как она работает сейчас. Если после смены версии PHP результат изменился, вы увидите это сразу.
Начните с самого ценного: регистрации и входа, оформления заказа, расчёта цен и скидок, генерации документов, интеграций с платёжными системами. Подойдут PHPUnit, Codeception или обычные HTTP-запросы к тестовому стенду с проверкой ответа. Если юнит-тесты написать трудно из-за запутанного кода, начните с сквозных тестов: они грубее, но защищают от самых дорогих ошибок.
- 01PHP 5.6 → 7.4
Исчезают функции mysql_* и ereg, устаревают конструкторы по имени класса. Обычно это самый трудоёмкий скачок: нужно переписать работу с БД на PDO или mysqli.
- 02PHP 7.4 → 8.0
Удаляются create_function() и each(), меняется сравнение строк и чисел, многие предупреждения превращаются в исключения TypeError и ValueError.
- 03PHP 8.0 → 8.2
Передача null во встроенные функции даёт Deprecated, а динамические свойства классов объявляются устаревшими. Лог заполняется предупреждениями — их нужно вычистить.
- 04PHP 8.2 → 8.3
Самый спокойный шаг: чаще всего достаточно обновить зависимости и проверить тесты. Можно начинать использовать новые возможности языка.
Что именно ломается при смене версии
Большинство проблем при обновлении повторяются от проекта к проекту. Это удалённые функции, ужесточённые проверки типов и изменённые правила сравнения значений. Хорошая новость в том, что такие вещи хорошо находятся автоматически. Статический анализатор и PHPCompatibility покажут проблемные места ещё до запуска, а Rector исправит часть из них сам.
В таблице ниже собраны самые частые случаи, с которыми сталкиваются при переходе на PHP 7 и 8.
| Что изменилось | Как проявляется | Что делать |
|---|---|---|
| Удалены функции mysql_* | Fatal error: вызов неопределённой функции mysql_connect() | Перейти на PDO или mysqli и вынести доступ к БД в отдельный слой |
| Удалены create_function() и each() | Fatal error при запуске скрипта на PHP 8 | Заменить на анонимные функции и foreach, Rector делает это автоматически |
| Новые правила сравнения строк и чисел, например «abc» == 0 | Условия срабатывают иначе, чем раньше, и логика молча ломается | Применять строгое сравнение === и явное приведение типов |
| Передача null во встроенные функции | Deprecated в логах, ошибки при включённом строгом режиме | Добавить проверки на null, значения по умолчанию, оператор ?? |
| Динамические свойства классов | Deprecated в PHP 8.2, потенциальная ошибка в будущих версиях | Объявить свойства в классе; атрибут AllowDynamicProperties использовать лишь как временную меру |
Зависимости и Composer: обновлять с умом
Нередко именно сторонние пакеты тормозят обновление сильнее, чем собственный код. Библиотека, которую не обновляли пять лет, может не поддерживать PHP 8. Начните с команды composer outdated: она покажет, какие пакеты отстали и насколько. Команда composer audit сообщит об известных уязвимостях. Затем для каждой проблемной библиотеки примите решение: обновить, заменить аналогом или вынести нужную часть в собственный код.
Если проект построен на фреймворке (Laravel, Symfony, Yii) или CMS вроде 1С-Битрикс, сначала сверьтесь с таблицей совместимости версий и требованиями ядра и модулей. Иногда обновление PHP придётся делать вместе с обновлением самого фреймворка, и тогда их тоже нужно разбить на шаги. Параметры platform в composer.json помогут проверить, что зависимости подбираются под целевую версию PHP, а не под ту, что сейчас установлена на сервере.
Показывают устаревшие пакеты и известные уязвимости в зависимостях.
Находят ошибки типов и обращения к несуществующим методам без запуска кода.
Стандарт для PHP_CodeSniffer: перечисляет конструкции, не работающие на целевой версии.
Автоматически переписывает устаревший код по наборам правил под нужную версию PHP.
Фиксируют поведение системы до и после каждого шага обновления.
Позволяет параллельно запускать проект на разных версиях PHP и сравнивать результат.
Как не навредить работающему проекту
Самые болезненные провалы при обновлении происходят не из-за сложности кода, а из-за спешки и смешения задач. Команда одновременно меняет версию PHP, переписывает модули и добавляет новые функции. Когда после релиза что-то ломается, невозможно понять, какое именно изменение стало причиной.
Поэтому обновление лучше выделить в отдельный проект с понятными границами. Ниже — ошибки, которые встречаются чаще всего, и способы их избежать.
Типичные ошибки при обновлении legacy PHP
Как делают неправильно
- Обновляют PHP на сервере напрямую, без копии окружения и без тестов
- Перескакивают через несколько мажорных версий за один раз
- Совмещают обновление с редизайном, новыми функциями и переписыванием модулей
- Отключают вывод ошибок и Deprecated, чтобы логи «не мешали»
- Выкатывают релиз для всех пользователей сразу, без плана отката
Как правильно
- 01
Сначала воспроизвести продакшен в Docker и прогнать тесты на целевой версии
- 02
Идти по цепочке версий, фиксируя результат каждого шага отдельным коммитом
- 03
Выделить обновление в отдельную ветку и отдельную задачу, без новых функций
- 04
Включить полный вывод ошибок на стейджинге и последовательно устранить каждое предупреждение
- 05
Использовать канареечный или blue-green релиз и держать готовый откат на предыдущую версию
Релиз, мониторинг и SEO-безопасность
Релиз — это не конец работы, а начало наблюдения. Подключите сбор ошибок (например, Sentry или стандартные логи PHP-FPM) и первые дни после выкатки внимательно следите за новыми исключениями, скоростью ответа и потреблением памяти. Если используете blue-green деплой, держите старую версию окружения включённой, пока не убедитесь, что новая стабильна.
Для сайтов, которые приносят органический трафик, важно проверить и поисковую сторону. Смена версии PHP сама по себе не влияет на позиции, но ошибки 5xx, медленные ответы и сбои в формировании страниц могут навредить индексированию. Следите за отчётами Яндекс Вебмастера и Google Search Console: ошибки сервера, статус индексирования, доступность sitemap и robots.txt. Одновременно сравните поведение посетителей в Яндекс Метрике и Google Analytics до и после релиза. Резкое падение конверсии или рост отказов часто указывает на скрытую ошибку в форме или корзине.
Стейджинг отработал неделю на целевой версии без новых предупреждений.
Вход, корзина, оплата и формы покрыты тестами и проходят успешно.
PHPStan или Psalm на согласованном уровне не находят новых проблем.
Возврат на прежнюю версию проверен заранее и описан в инструкции.
С чего начать прямо сейчас
- 01
Зафиксируйте версию PHP, расширения и зависимости, поднимите копию проекта в Docker
- 02
Запустите composer outdated, composer audit и статический анализ, чтобы увидеть реальный объём работ
- 03
Напишите тесты на самые важные бизнес-сценарии
- 04
Двигайтесь по одной версии PHP за раз и релизьте с готовым планом отката
Начните с аудита: он покажет, сколько проблем скрыто в коде и зависимостях, и позволит оценить сроки без догадок. Чем раньше вы разберёте накопившийся технический долг, тем дешевле и спокойнее пройдёт переход на актуальную версию PHP. Если нужна помощь, мы проведём аудит проекта и составим пошаговый план обновления.
Часто задаваемые вопросы
Технически можно, но делать это не рекомендуется. Ошибки накладываются друг на друга, и найти причину сбоя трудно. Надёжнее идти по цепочке 5.6 → 7.4 → 8.0 → 8.1 → 8.3. После каждого шага запускайте тесты и проверяйте логи.
Используйте PHPCompatibility для PHP_CodeSniffer, статические анализаторы PHPStan и Psalm, а также Rector в режиме dry-run. Они показывают устаревшие и удалённые конструкции до запуска на сервере.
Сначала напишите характеризационные тесты на критичные сценарии: авторизацию, оформление заказа, оплату, отправку форм. Они фиксируют текущее поведение системы. Покрывать 100% кода не нужно, достаточно ключевых бизнес-путей.
Не меняйте URL и структуру страниц вместе с версией PHP. После релиза следите за ошибками 5xx и индексированием в Яндекс Вебмастере и Google Search Console, а также за поведением посетителей в Яндекс Метрике и Google Analytics.
Срок зависит от размера кодовой базы, качества зависимостей и наличия тестов. Небольшой проект обычно обновляют за несколько недель. Большой монолит с устаревшими библиотеками может занять несколько месяцев. Для оценки проведите аудит и пробный прогон Rector и PHPStan.
Получите план безопасного обновления вашего PHP-проекта до актуальной версии
Проведём аудит кода и зависимостей и подготовим пошаговую дорожную карту миграции с оценкой сроков.
Спасибо за заявку!
Мы свяжемся с вами в ближайшее время.
Обновляем проекты без остановки продаж



