Переход с PHP 7.4 на PHP 8: пошаговый план миграции
Открытый ящик с ровным рядом белых шайб, одна из которых наклонена и зелёная, рядом лежит снятая крышка

Переход с PHP 7.4 на PHP 8: пошаговый план миграции

Переход с PHP 7.4 на PHP 8 безопасен, если заранее проверить совместимость: обновить зависимости, прогнать статанализ и тесты, затем выкатывать поэтапно.

Переход с PHP 7.4 на PHP 8: что нужно знать до начала

Перейти с PHP 7.4 на PHP 8 можно без остановки проекта, если действовать по порядку: проверить совместимость кода и библиотек, поймать ошибки статическим анализом и тестами, проверить работу на staging и выкатывать поэтапно с возможностью отката.

PHP 7.4 больше не получает даже исправлений безопасности: поддержка закончилась 28 ноября 2022 года.

В этой статье разберём, зачем обновляться, какие изменения в PHP 8 действительно ломают старый код, какими инструментами автоматизировать проверку и как построить безопасный план миграции. Материал подойдёт и для небольшого сайта на CMS, и для крупного приложения на Laravel, Symfony или самописном ядре.

Почему откладывать обновление опасно

Главный довод за миграцию не новые возможности, а безопасность. Когда ветка PHP выходит из поддержки, найденные уязвимости в ней больше не закрываются. Если вы работаете на 7.4, любая новая брешь в интерпретаторе остаётся с вами навсегда. Хостинг-провайдеры постепенно убирают такие версии из панели управления, а сканеры безопасности и требования заказчиков помечают устаревший PHP как риск.

Вторая причина экосистема. Современные версии популярных пакетов, фреймворков и CMS постепенно поднимают минимальную версию PHP. Пока вы сидите на 7.4, вы не получаете обновления зависимостей, и технический долг растёт. Чем дольше пауза, тем больше накопленных изменений придётся разбирать за один раз.

Третья причина инженерная. Код на PHP 8 проще читать и поддерживать: появились именованные аргументы, атрибуты, promotion свойств в конструкторе, union-типы, выражение `match` и nullsafe-оператор. Всё это сокращает шаблонный код и делает типы явными.

Что вы получаете после перехода на PHP 8

  1. 01

    Актуальные исправления безопасности и поддержку, пока выбранная ветка находится в жизненном цикле

  2. 02

    Доступ к свежим версиям фреймворков, CMS и Composer-пакетов, которые уже не поддерживают 7.4

  3. 03

    Более строгую и предсказуемую работу с типами: ошибки, которые раньше молча скрывались, становятся заметными

  4. 04

    Современный синтаксис: `match`, nullsafe `?->`, именованные аргументы, атрибуты, constructor promotion, union-типы

  5. 05

    Новые функции `str_contains()`, `str_starts_with()`, `str_ends_with()`, которые заменяют громоздкие проверки через `strpos()`

  6. 06

    JIT-компилятор и общие оптимизации движка: заметный прирост на вычислениях и умеренный в типичных веб-задачах

жизненный цикл веток php

Где сейчас находится 7.4 и куда двигаться

7.428.11.2022поддержка завершена
8.026.11.2023поддержка завершена
8.131.12.2025конец security-поддержки
8.231.12.2026конец security-поддержки
8.331.12.2027конец security-поддержки

Даты указаны по официальному графику PHP на момент подготовки статьи. Перед планированием релиза сверьтесь со страницей поддерживаемых версий на сайте php.net.

Какую версию PHP 8 выбирать

Формально вы переходите «на PHP 8», но на практике нужно выбрать конкретную ветку: 8.0, 8.1, 8.2, 8.3 или новее. Останавливаться на 8.0 бессмысленно: она уже вышла из поддержки, и вы окажетесь в той же ситуации, что и сейчас. Выбирайте ветку, у которой впереди есть хотя бы год-два жизненного цикла, и убедитесь, что её поддерживают ваши хостинг, CMS и ключевые пакеты.

Переход через несколько версий сразу допустим, но тогда в тестах нужно учитывать депрекейты каждой промежуточной ветки. Например, в 8.1 устарела передача `null` в необязательные для null параметры внутренних функций, в 8.2 объявлены устаревшими динамические свойства классов, а в 8.4 неявные nullable-типы параметров. Эти предупреждения не ломают работу, но засоряют логи и в будущих версиях превратятся в ошибки.

Что действительно ломается при переходе с 7.4 на 8.0

Большинство проектов упирается в несколько повторяющихся групп проблем. Разберём их по степени распространённости.

1. Сравнение строк и чисел. В PHP 8 изменена логика нестрогого сравнения. Раньше `0 == 'abc'` возвращало `true`, потому что строка приводилась к числу. Теперь число приводится к строке, если вторая сторона не является числовой, и результат будет `false`. Такой код часто встречается в проверках прав доступа, статусов и условий в шаблонах.

2. Ошибки вместо тихих предупреждений. Внутренние функции теперь выбрасывают `TypeError` и `ValueError` при неверных аргументах, а не возвращают `null` или `false` с предупреждением. Арифметика и побитовые операции над массивами, ресурсами и объектами тоже приводят к `TypeError`.

3. Необъявленные переменные и ключи. Обращение к несуществующей переменной или ключу массива теперь даёт Warning, а не Notice. Если на проде включён вывод ошибок или обработчик превращает предупреждения в исключения, сайт может начать падать там, где раньше работал.

4. Удалённые возможности. Исчезли `create_function()`, `each()`, приведение `(real)`, доступ к символам строки через фигурные скобки `$str{0}`, а также методы-конструкторы в стиле PHP 4 (метод с именем класса).

5. Объекты вместо ресурсов. Функции расширений curl, GD, XML и других теперь возвращают объекты (`CurlHandle`, `GdImage` и т. д.). Проверка `is_resource()` на таких значениях вернёт `false`.

6. Приоритет оператора конкатенации. Знаки `+` и `-` теперь имеют более высокий приоритет, чем точка. Выражение вида `'Итого: ' . $a + $b` теперь вычисляется иначе, чем в 7.4. Лучше явно расставить скобки.

было / стало

Три изменения, которые чаще всего ломают рабочий код

01
42 == '42abc'
php 7.4true
php 8false
02
0 == 'abc'
php 7.4true
php 8false
03
is_resource(curl_init())
php 7.4true
php 8false

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

Как было в PHP 7.4Как в PHP 8Что делать
Ошибка во внутренней функции давала предупреждение и возврат null или falseВыбрасывается TypeError или ValueErrorПроверять входные данные и обернуть рискованные вызовы в try/catch там, где это оправдано
Необъявленная переменная или ключ массива давали NoticeВыдаётся Warning: Undefined variable, Undefined array keyИнициализировать переменные, использовать isset(), ?? и array_key_exists()
create_function() и each() работали (с депрекейтом)Функции удалены, вызов приводит к фатальной ошибкеЗаменить на анонимные функции и foreach
Символ строки можно было получить через $str{0}Синтаксис удалён, остаются квадратные скобки $str[0]Перейти на квадратные скобки или mb_substr() для многобайтных строк
curl_init() и imagecreate() возвращали resourceВозвращаются объекты CurlHandle и GdImageЗаменить is_resource() на проверку instanceof или сравнение с false

Чем автоматизировать проверку совместимости

Искать такие места глазами в проекте на сотни файлов неэффективно. Для этого есть инструменты, и использовать их лучше в связке.

Статический анализ. PHPStan и Psalm находят вызовы с неверными типами аргументов, обращения к несуществующим свойствам и методам, потенциально неинициализированные переменные. Запустите их на целевой версии PHP и начните с умеренного уровня строгости, поднимая его постепенно.

Проверка совместимости. Набор правил PHPCompatibility для PHP_CodeSniffer сканирует код на использование удалённых и устаревших возможностей для выбранной версии. Он быстро даёт список мест, которые точно нужно править.

Автоматический рефакторинг. Rector умеет безопасно переписывать типовые конструкции под новую версию: заменять `strpos()` на `str_contains()`, добавлять promotion свойств, обновлять устаревший синтаксис. Всегда просматривайте дифф перед коммитом, а не принимайте изменения вслепую.

Зависимости. Команда `composer why-not php 8.3` покажет, какие пакеты блокируют обновление. Часть библиотек потребуется обновить, а заброшенные заменить на живые аналоги или форкнуть.

Тесты. Никакой анализатор не заменит прогон автотестов на новой версии. Если покрытия нет, хотя бы напишите smoke-тесты на ключевые сценарии: авторизацию, оформление заказа, формы, API.

Пошаговый план миграции на PHP 8

  1. 01

    Проведите инвентаризацию. Выпишите текущую версию PHP, список расширений (`php -m`), версии CMS или фреймворка, все Composer-пакеты и плагины, а также cron-скрипты и воркеры очередей.

  2. 02

    Зафиксируйте целевую версию и проверьте, поддерживают ли её хостинг, веб-сервер, база данных и ваша CMS. Если нужно, сначала обновите фреймворк или CMS до версии, совместимой с PHP 8.

  3. 03

    Обновите зависимости. Измените ограничение `php` в `composer.json`, выполните `composer update` в отдельной ветке и разберите конфликты. Заброшенные пакеты заменяйте или форкайте.

  4. 04

    Запустите PHPCompatibility, PHPStan или Psalm и исправьте найденное. Типовые правки автоматизируйте через Rector, а результат проверяйте вручную.

  5. 05

    Поднимите staging-окружение с той же версией PHP и теми же расширениями, что планируются на проде. Включите `error_reporting = E_ALL` и логирование, прогоните автотесты и ручные сценарии.

  6. 06

    Проверьте производительность и память: сравните время ответа, нагрузку на CPU и потребление памяти на типичных страницах и тяжёлых запросах до и после обновления.

  7. 07

    Выкатите поэтапно. Если инфраструктура позволяет, переведите на PHP 8 сначала часть трафика или один сервер, наблюдайте за логами и метриками, затем остальные. Заранее подготовьте быстрый откат на 7.4.

Конфигурация и расширения не забываем

Код это только половина миграции. После смены версии стоит перепроверить `php.ini` и конфигурацию пула PHP-FPM: значения по умолчанию и поведение некоторых директив менялись. Убедитесь, что установлены все нужные расширения именно под PHP 8: `mbstring`, `intl`, `curl`, `gd` или `imagick`, `pdo_mysql` или `pdo_pgsql`, `opcache`, `redis`, `zip`. Расширения из PECL нужно ставить заново под новую версию, а старые бинарные сборки не подойдут.

Отдельно проверьте OPcache и JIT. OPcache нужно включать в любом случае, он даёт основной выигрыш в скорости. JIT включайте осознанно и только после замеров: для типичного сайта на CMS он почти не меняет результат, а вот в вычислительных задачах может помочь заметнее.

Не забудьте про окружение разработки. Docker-образы, CI-пайплайны, локальные среды и конфигурации IDE должны использовать ту же версию PHP, что и прод. Иначе ошибки будут выявляться уже после релиза.

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

Большинство неудачных миграций проваливаются не из-за самого PHP 8, а из-за спешки и отсутствия проверки на реальных данных.

Как делают неправильно

  • Обновляют PHP сразу на продакшене без staging-окружения
  • Скрывают предупреждения через `error_reporting(0)` или оператор `@`, чтобы «всё заработало»
  • Не проверяют Composer-зависимости и плагины CMS, а потом получают белый экран
  • Опираются только на то, что главная страница открылась
  • Не готовят план отката и не делают резервную копию

Как правильно

  1. 01

    Тестировать на staging с идентичным окружением и копией реальных данных

  2. 02

    Включить `E_ALL`, собрать предупреждения в логи и исправить их причины, а не симптомы

  3. 03

    Заранее выполнить `composer why-not` и проверить совместимость каждого плагина и темы

  4. 04

    Прогнать сценарии: авторизация, формы, оплата, личный кабинет, API, cron, очереди

  5. 05

    Сделать бэкап, сохранить рабочий пул 7.4 и выкатывать поэтапно

Что отслеживать после релиза

Выкатив PHP 8, не расслабляйтесь сразу. Первые часы и дни следите за логами ошибок PHP и веб-сервера, ростом числа 5xx-ответов, временем ответа и потреблением памяти. Часть проблем проявляется только на редких сценариях: ночных cron-задачах, экспорте отчётов, обработке старых записей.

Для сайтов, которые зависят от поискового трафика, добавьте внешний контроль. Яндекс Вебмастер и Google Search Console покажут ошибки обхода, недоступность страниц и проблемы с индексацией. Яндекс Метрика и Google Analytics помогут увидеть всплески отказов, падение конверсии или проседание скорости загрузки. Если после релиза появились скачки 5xx или аномалии в поведении, откатывайтесь и разбирайтесь на staging, а не чините на живом трафике.

чек-лист перед релизом

Готов ли проект к PHP 8

  • composer updateпроходит без конфликтов на целевой версии
  • PHPCompatibility и PHPStan не показывают критичных ошибок
  • Автотесты и ручные сценарии пройдены на staging сE_ALL
  • Установлены все расширения под PHP 8, настроены OPcache и PHP-FPM
  • Cron-задачи, воркеры очередей и консольные команды запущены под новой версией
  • Есть свежий бэкап и отработанный сценарий отката на 7.4
Если проект работает на готовой CMS или фреймворке, начинайте не с PHP, а с проверки требований вашей платформы и всех установленных плагинов и модулей. Часто достаточно обновить именно их, и значительная часть проблем уйдёт сама.

Итоги: как перейти на PHP 8 спокойно

Миграция с PHP 7.4 на PHP 8 — это не прыжок в неизвестность, а управляемый процесс из нескольких проверок.
  1. 01

    Выберите целевую ветку, у которой впереди живой жизненный цикл, и проверьте её поддержку хостингом и платформой

  2. 02

    Обновите зависимости и прогоните PHPCompatibility, PHPStan или Psalm и Rector

  3. 03

    Особое внимание уделите сравнению строк с числами, ошибкам во внутренних функциях, необъявленным переменным и объектам вместо ресурсов

  4. 04

    Протестируйте на staging с E_ALL, затем выкатывайте поэтапно с готовым планом отката

  5. 05

    После релиза следите за логами, 5xx-ответами и данными Яндекс Вебмастера, Google Search Console, Яндекс Метрики и Google Analytics

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

Часто задаваемые вопросы

Обновим PHP на вашем проекте без простоя и потери данных

Проведём аудит совместимости кода и зависимостей и составим пошаговый план миграции на PHP 8

Бесплатный аудитРелиз без простояПлан отката

Миграции проводим на staging с откатом

Политика конфиденциальности

При оставлении заявки на ресурсе «https://gurucontext.ru» пользователи предоставляют следующие сведения:

  • Имя
  • Контактный телефон или Telegram
  • Адрес сайта пользователя (не обязательно)

Также администрация сайта получает данные об IP-адресе посетителей, типе браузера, времени нахождения на сайте и прочие подобные сведения через сервисы статистики.

Использование информации

Вся полученная информация используется администрацией «https://gurucontext.ru» исключительно в целях связи с клиентом.

Защита персональных данных

Компания «https://gurucontext.ru» обязуется не разглашать сведения, полученные от пользователей, и хранит их в защищённом виде.

Предоставление данных третьим лицам

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

Контакты

Телефон: +7 (499) 955-47-00.
E-mail: info@gurucontext.ru.