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

PHP и UTF-8: четвёртый этап

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

Какие у нас есть варианты? Функцию preg_replace_callback мы рассмотрели ещё в прошлый раз (а я это сделал сегодня, ничего криминального не нашёл), но есть и другие callback-функции, а так же eval, регулярные выражения с ключом «e» (PREG_REPLACE_EVAL), call_user_func, call_user_func_array и create_function.

Начнём с eval, его проще всего найти:

bolk@dev:~/daproject$ find -type f ( -name '*.php' -or -name '*.tpl' -or -name '*.inc' ) | xargs -n1 egrep -li 'bevals*('
./php/lib/magpierss/extlib/Snoopy.class.inc
./php/lib/PEAR.php
./php/dir1/file1.php
./php/dir1/file2.php
./php/dir1/file3.php

К счастью, почти всё что я нашёл — это eval-вызовы в коде на JavaScript внутри PHP-скриптов, так что править мне ничего не пришлось. В вызовах call_user_func, call_user_func_array и create_function я так же ничего криминального не нашёл (проверяются точно так же).

Теперь я попробую найти вообще все callback-функции. Это чуть сложнее сделать — в руководстве по PHP раздела, где они были бы перечислены нет. В chm-версии руководства я просто поискал строку «callback».

Не все callback-функции нас интересуют, нужны только те, которые возвращают строковый результат. Кроме того, нужно поискать использование констант, которые задают в некоторых вызовах callback-функции.

Вот что у меня получилось: readline_callback_handler_install, readline_callback_read_char, ob_start, session_set_save_handler, CURLOPT_HEADERFUNCTION, CURLOPT_PASSWDFUNCTION, CURLOPT_PROGRESSFUNCTION, CURLOPT_READFUNCTION, CURLOPT_WRITEFUNCTION, FILTER_CALLBACK, iterator_apply, set_exception_handler, pcntl_signal, array_map, array_filter, array_walk, array_walk_recursive, array_udiff_uassoc, array_diff_uassoc, array_udiff_assoc, array_diff_ukey, array_udiff , array_intersect_ukey, array_uintersect_uassoc, array_uintersect_assoc, array_intersect_uassoc, array_intersect_assoc , array_uintersect, array_reduce, uksort, usort, uasort.

Или для командной строки (регулярное выражение я тут подсократил):

bolk@dev:~/daproject$ find -type f ( -name '*.php' -or -name '*.tpl' -or -name '*.inc' ) |
> xargs -n1 egrep -H 'array_map|array_filter|array_walk|…|uasort' | less

В выводе нужно высматривать только вызовы строковых функций и статических методов, которые стоят на месте callback-параметров или переменные на тех же местах, в последнем случае нужно будет детально разобрать что находится в этих переменных. У меня на это ушло две минуты, это в проекте с 50000 строк кода.

Всё, что осталось найти — вызовы preg_replace с модификатором «e». Я, было, подумал как-то автоматизировать это дело, но просмотрел сколько у меня вхождений этой функции — оказалось около 200, быстрее просмотреть глазами. Мои старания были вознаграждены — я сделал несколько замен.

Думаю, в следующей части надо что-то сделать с явными указаниями кодировки. Впрочем, я ещё не решил.

2 комментария
Бресь Сергей (bressergey.com) 2010

А «один большой веб-сервис» — это всё, что вы можете раскрыть о проекте?
Уж очень он от души PHP-возможности всякие использует.
Интересно...

Евгений Степанищев (bolknote.ru) 2010

Комментарий для bressergey.com:

Это внутренняя Вики.