Пишу, по большей части, про историю, свою жизнь и немного про программирование.

Переезд на PHP7

В почте попросили описать переезд на ПХП7, с какими сложностями встретились, как они решались. Опишу, пока не забыл — я этим занимался почти в одиночку, так как задача не была приоритетной. Я считал, что мы сможем получить хороший прирост производительности, поэтому сам её и делал в свободное время.

Если кому интересно, загруженность серверов, где крутится ПХП, действительно упала, примерно в 1,5—1,7 раза.

Вообще говоря, у ПХП есть довольно детальные описания того, что может пойти не так при смене версий, достаточно заглянуть в раздел «Изменения, ломающие обратную совместимость» нужной версии. Там можно сразу прикинуть что придётся поменять в коде, если вы хорошо его знаете.

Ниже мой собственный опыт.

Сначала я составил список всех модулей ПХП, которые у нас используются — натурально выписал из зависимостей пакета нашего продукта в табличку в местной «вики». На тот момент не все модули поддерживали «семёрку», поэтому к табличке я иногда возвращался и вносил изменения, если они случались.

Когда в табличке без поддержки остался единственный модуль ctwig от шаблонизатора «Твиг», решил, что без него мы можем обойтись — к этому времени в интернете появились замеры скорости и «Твиг» без модуля под «семёркой» демонстрировал похожие результаты с «пятёркой» и модулем.

Дальше я проверил не используются ли у нас где-то новые зарезервированные слова. Так как их использование вызовает ошибку синтаксиса, то случаи использования легко ловятся скриптом наподобие этого:

find . -type f \( -name '*.php' -o -name '*.inc' \) -exec php -l {} \; |
fgrep -v 'No syntax errors'

У нас, к слову, было несколько таких мест — например, был объявлен класс с разными полезными штуками для обработки строк, который назывался String. Так больше нельзя — зарезервированное слово.

Посложнее с обработкой исключений — класс Exception перестал быть базовым и если требуется ловить все исключения, то в «семёрке» лучше всего перехватывать всё, что реализует интерфейс Throwable.

У нас необработанные кодом исключения ловятся и пишутся в логи, для этого в нескольких местах кода есть перехват всего подряд. Выглядело это примерно так:

try {
    // … какой-то код
} catch (Exception $e) {
   DI::log->get('exception')->error($e);
   throw $e;
}

Из-за пространства имён такие места простым поиском найти непросто, но специализированные редакторы неплохо справляются.

Несложными регулярками поискал различные непрямые выражения, там теперь тоже есть разница, нашёл всего несколько штук и поправил.

Потом я как-то походя заметил «нотисы», связанные с модулем Memcached и оказалось, что этого модуля сменилось АПИ, а в документации об этом не слова, пришлось писать прокси-класс. Сейчас документация уже обновлена, прокси мы убрали и просто переписали затронутые места.

Далее в дело вступили тестеры и программисты — в основном были исправления, связанные с тем, что в «семёрки» некоторые вещи устарели, ничего сверх этого я не припомню.

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

2 комментария
Валерий 2018

Евгений, а вы именно на 7.0 перешли? Я недавно перевел сайты на 7.1, и самая бесячая ошибка — «A non-numeric value encountered in ...», когда пустая строка в математических выражениях (’’ + 1) не интерпретируется как 0, а вызывает ворнинг.

Евгений Степанищев 2018

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