Миграция с PHP 5.2 на PHP 5.3.

Jul 14, 2010 17:17



Предпосылки к миграции:
1) Желание иметь свежий софт, очевидно обусловлено желанием использовать новые баги фичи, новый софт всегда лучше, правда? *приторно розовые очки*
2) Ветка 5.3 релизнулась уже год назад(30 июня 2009), в начале марта этого года релизнули версию  5.3.2, а это обещает некоторую стабильность.
3) Ubuntu lucid, новый сервер с длинным сроком поддержки - 5 лет от Canonical поставляет версию PHP 5.3, как единственно возможную, а это значит наша компанию будет жить с этим дистрибутивом как минимум ближайшие 2.5 года.

Поддерживать на новой системе мне необходимо было некий проприетарный софт, который частично предоставляет сырцы, частично шифрован с помощью ioncube.

Основная загвоздка с которой пришлось столкнуться это то что часть функций получили статус deprecate. В частности получила данный статус функция split, по очевидным причинам, но продукт не мой и он должен работать.

Что происходит внутри PHP, когда он натыкается на некую deprecate функцию?
Он выставляет флаг ошибки данного класса(E_DEPRECATED) и выводит сообщение пользователю. Если же приложение сложное, например общается с внешним миром по какому-то протоколу типа SOAP, то ошибка предупреждения может заблокировать работу приложения(и как следствие пользователя).

Что можно придумать?

1) Самый просто и правильный способ, запретить сообщения данного класса ошибок.

Для этого в php.ini надо выставить:

error_reporting = E_ALL & ~E_DEPRECATED

2) display_errors = Off

Сходный с первым способом, но будет подавлять вывод всех ошибок.

3) 1й и 2й способ может не помочь, если переменная error_reporting и/или display_errors  переопределяются внутри приложения, например с помощью функции error_reporting или ini_set.

Можно попробовать заменить deprecate функции в коде.

Для функции split это можно осуществить с помощью 2х замен:
а) если нужно заменить некий набор символов, тогда split можно заменить на explode
б) если split использует регулярные выражения, то можно заменить на preg_split
Правда тут замена будет немного сложнее из-за разницы форматов регулярных выражений, выглядеть замена будет примерно так:
-$parts = split('[[:space:]]+', trim($uname));
+$parts = preg_split('/\s+/', trim($uname));

4) Поискать где же переопределены error_reporting и/или display_errors и им подобные, поправить их в коде.

5) Этот способ в какой то мере самый сложный и самый НЕ правильный, им стоит пользоваться, если не помогли предшествующие.

Мне подошел именно он, из-за того, что переопределение переменных и использование deprecate функций в приложении оказались зашифрованными.

Мы полезем грязными руками в ядро php. В этот же основная сила opensource, не правда ли?)

Нам нужно исключить фунцию/функции из списка запрещенных.

Скачав сырцы php-5.3.2 под ubuntu lucid, я был уверен, что задача окажется простой.
Мне всегда интересно анализировать, что могло сподвигнуть разработчика на тот или иной шаг.

Тут надо сказать что deprecat`ы это основная не совместимость между ветками php. Что бы смягчить несовместимость в данном случае, мне лично хочется сделать ее максимально легко выдираемой и с кучей красочных комментариев, что нибудь вроде «DEPRECATED LIST FUNCTION»,  написать список функций plaintext и подставлять в код с помощью сборочной системы. Получился бы качественный UnixWay. Но нет, программисты ZEND думаю совсем иначе. Мне кажется их логика была примерно: «как бы поглубже закопать, что бы никто не догадался как выдрать deprecate функции». Они не оставили ни одного комментария в коде на этот счет, а в функцию обертку добавили всего 3 символа DEP, больше ничего.

Перейдем собственно к вопросу как решить нашу задачу и избавиться от навязчивого сообщения.

Пару часов работы grep и вуаля =)

Правильная строка для поиска:

grep -r "DEP_FE" ../* 2>&1 |grep split

В результате нужно найти строку похожую на эту:
php5-5.3.2/ext/ereg/ereg.c:    PHP_DEP_FE(split,                   arginfo_split)

Тут достаточно заменить функцию обертку:
s/PHP_DEP_FE/PHP_FE/

Как не трудно догадаться разработчики Zend сделали обертку для функций вызова.

Определены обертки в файле:
php5-5.3.2/Zend/zend_API.h

Вот разница между вызовами:

#define PHP_FE                  ZEND_FE
#define PHP_DEP_FE      ZEND_DEP_FE

#define ZEND_FE(name, arg_info)                                         ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
#define ZEND_DEP_FE(name, arg_info)                 ZEND_FENTRY(name, ZEND_FN(name), arg_info, ZEND_ACC_DEPRECATED)

6) Можно было бы пересобрать php другой версии, но сделать это в соответствии с debian way довольно муторное занятие.

7) Откатываться на предшествующую версию ОС, где уже есть PHP другой версии, но это мне показалось и вовсе не приемлемым вариантом.

ЗЫ Есть еще некоторые вещи с которыми можно поманипулировать в данном случае, например:
disable_functions
auto_prepend_file

Но они не помогли в моем случае.

php

Previous post Next post
Up