Почему PHP 8 ломает старый код
PHP 8.0 (выпущен 2020) и PHP 8.1/8.2 сделали язык более строгим. Функции, которые были «устаревшими» (deprecated) в PHP 7.x (то есть ещё работали, но с предупреждением), в PHP 8 стали фатальными ошибками.
Если ваш сайт сломался после обновления сервера, почти наверняка причина в одном из этих пунктов.
Самые распространённые проблемы
1. Функции mysql_* (удалены в PHP 7, фатальная ошибка в PHP 8)
// НЕ РАБОТАЕТ — полностью удалено
$conn = mysql_connect("localhost", "user", "pass");
$result = mysql_query("SELECT * FROM products");
// ИСПРАВЛЕНО — используйте mysqli или PDO
$conn = new mysqli("localhost", "user", "pass", "dbname");
$result = $conn->query("SELECT * FROM products");
Если вы до сих пор используете mysql_*, вашему коду как минимум 10 лет. Переписывание простое, но трудоёмкое для больших кодовых баз.
2. ereg() и ereg_replace() (удалены в PHP 7)
// НЕ РАБОТАЕТ
if (ereg("^[a-z]+$", $str)) { ... }
$clean = ereg_replace("[^a-z0-9]", "", $str);
// ИСПРАВЛЕНО — используйте эквиваленты preg_
if (preg_match("/^[a-z]+$/", $str)) { ... }
$clean = preg_replace("/[^a-z0-9]/", "", $str);
3. create_function() (удалена в PHP 8.0)
// НЕ РАБОТАЕТ
$fn = create_function('$x', 'return $x * 2;');
// ИСПРАВЛЕНО — используйте анонимную функцию
$fn = function($x) { return $x * 2; };
// или стрелочную функцию
$fn = fn($x) => $x * 2;
4. each() (удалена в PHP 8.0)
// НЕ РАБОТАЕТ
while (list($key, $val) = each($array)) { ... }
// ИСПРАВЛЕНО
foreach ($array as $key => $val) { ... }
5. Глобальные переменные $HTTP_*_VARS (давно исчезли, но ещё есть в старом коде)
// НЕ РАБОТАЕТ — эти переменные отсутствуют с PHP 5.4
$id = $HTTP_GET_VARS['id'];
$name = $HTTP_POST_VARS['name'];
// ИСПРАВЛЕНО
$id = $_GET['id'];
$name = $_POST['name'];
6. Передача null в параметры, не допускающие null (PHP 8.1)
Это коварная проблема, которая ломает немало более современного кода:
// НЕ РАБОТАЕТ в PHP 8.1 — strlen не принимает null
$len = strlen(null); // Фатальная ошибка: strlen(): Argument #1 must be of type string, null given
// ИСПРАВЛЕНО
$len = strlen($value ?? '');
// или
$len = $value !== null ? strlen($value) : 0;
Это возникает, когда переменные, которые могут быть null, передаются в функции, ожидающие строку или целое число. Часто встречается с результатами базы данных, где столбец может быть NULL.
7. Арифметические операции над строками (PHP 8.0)
// Раньше работало, теперь TypeError в PHP 8
$total = "10" + "20abc"; // Раньше: 30, теперь: TypeError
// ИСПРАВЛЕНО — явное приведение типов
$total = (int)"10" + (int)"20abc"; // 30
8. ReflectionParameter::getClass() (PHP 8.0)
Код фреймворков часто использует рефлексию. Этот метод был удалён:
// НЕ РАБОТАЕТ
$class = $param->getClass();
// ИСПРАВЛЕНО
$type = $param->getType();
if ($type instanceof ReflectionNamedType && !$type->isBuiltin()) {
$class = new ReflectionClass($type->getName());
}
Как найти все проблемы сразу
Вариант 1: Проверка совместимости с PHP
Установите php-compatibility с помощью PHPCS:
composer global require squizlabs/php_codesniffer
composer global require phpcompatibility/php-compatibility
phpcs --standard=PHPCompatibility --runtime-set testVersion 8.0 /path/to/your/code
Это просканирует всю вашу кодовую базу и перечислит все проблемы совместимости с файлами и строками.
Вариант 2: Включите логирование ошибок сначала
Если вы не можете запустить статический анализатор, хотя бы включите логирование ошибок:
// В php.ini или .htaccess
error_reporting = E_ALL
log_errors = On
error_log = /var/log/php_errors.log
display_errors = Off // Не показывать ошибки пользователям
Затем запустите каждую страницу и проверьте логи. Вы увидите, какие именно функции вызывают ошибки.
Вариант 3: Протестируйте на PHP 8 перед миграцией
Если ваш хостинг позволяет менять версию PHP, создайте копию сайта на PHP 8, запустите её на неделю и исправьте всё, что найдёте, перед переключением продакшена.
Специфические проблемы OpenCart с PHP 8
Если ваш сайт работает на OpenCart 2.x или ранней 3.x, вот как исправить самые распространённые проблемы:
Обновите ядро OpenCart
Зайдите в админ-панель, перейдите в меню System → Settings. Во вкладке General посмотрите версию. Если она ниже 3.0.3.8, скачайте последний патч с официального сайта OpenCart и установите через Extensions → Installer. Это исправит большинство проблем совместимости с PHP 8.Проверьте расширения
Отключите все сторонние модули (Extensions → Modules) по одному и проверьте, исчезает ли ошибка. Модули, написанные под старые версии PHP, часто используют устаревшие функции. Для каждого проблемного модуля обратитесь к его разработчику за обновлением или замените на современный аналог.Обновите модули оплаты
В разделе Extensions → Payments убедитесь, что все модули оплаты совместимы с PHP 8. Если нет — обновите их или обратитесь к разработчику.Настройте логирование ошибок
Включите логирование в админке: System → Settings → Server — включите "Log Errors" и просматривайте лог через System → Error Logs. Это поможет выявить, какие именно функции вызывают ошибки.
Если вы попробовали шаги выше и всё ещё не получилось (или не хотите делать это сами) — мы можем помочь с миграцией вашего сайта на PHP 8.