Когда пора мигрировать?
PHP 5.6 и 7.0 уже давно не поддерживаются. PHP 7.4 — последний в линейке 7.x, security-поддержка закончилась в ноябре 2022. Если ваш проект всё ещё на старой версии — вы рискуете безопасностью и совместимостью с новыми библиотеками.
Шаг 1: Аудит кода
Первым делом смотрим, что сломается. Используем phpcompatinfo или просто grep:
# Ищем устаревшие функции
grep -rn 'each(' app/
grep -rn 'create_function(' app/
grep -rn 'mysql_connect(' app/
grep -rn 'ereg(' app/
Самые частые проблемы:
each()— удалена в PHP 8.0create_function()— удалена в PHP 8.0mysql_*— удалены в PHP 7.0ereg/eregi— удалены в PHP 7.0
Шаг 2: Замена mysql на PDO/mysqli
Если проект использует mysql_* — это критично. Заменяем на PDO:
// Было
$conn = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('mydb', $conn);
$result = mysql_query("SELECT * FROM users WHERE id = $id");
// Стало
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);
$result = $stmt->fetchAll();
Шаг 3: Nullable и типы
PHP 8.0 изменил поведение многих функций:
// Было (работало в PHP 7.x)
strlen(null); // 0
// Стало (warning в PHP 8.0, error в 8.1+)
strlen(null); // Deprecated: Passing null to parameter #1 of type string
// Решение
strlen($str ?? '');
// или
strlen((string) $str);
Шаг 4: Named arguments
PHP 8.0 добавил именованные аргументы. Старый код может сломаться, если порядок параметров изменился:
// PHP 7.x — позиционные
str_contains($haystack, $needle);
// PHP 8.0+ — можно именованные
str_contains(haystack: $haystack, needle: $needle);
Шаг 5: Тестирование
Запускаем тесты на новой версии PHP:
# В Docker — легко переключить версию
docker run --rm -v $(pwd):/app -w /app php:8.2-cli php vendor/bin/phpunit
# Или через Sail
./vendor/bin/sail test
Фиксируем все падения, чиним по одному.
Шаг 6: Деплой
Деплоим на staging, тестируем ручные сценарии. Если всё ок — продакшен. Главное правило: не мигрируйте и не рефакторьте одновременно. Сначала — только версия PHP, потом — улучшения.
Итог
Миграция с PHP 5.6 на 8.2 — это 2-5 дней для типичного проекта. Большинство проблем решается поиском и заменой. Главное — не бояться и начинать с аудита.