← Back to blog
Blog

Как перевести легаси-проект с PHP 5.6 на PHP 8.2

Когда пора мигрировать?

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.0
  • create_function() — удалена в PHP 8.0
  • mysql_* — удалены в PHP 7.0
  • ereg/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 дней для типичного проекта. Большинство проблем решается поиском и заменой. Главное — не бояться и начинать с аудита.