PHP, UTF-8: восьмой этап, заключительный
Прошло уже немало времени, с тех пор как я описал предыдущий этап перевода
Для начала надо понять что же делать с чтением и записью файлов. Нет никакого автоматического способа решить что делать с этими операциями в вашем проекте, хорошие новости заключаются в том, что, скорее всего, ничего делать не придётся. Мне не пришлось, хотя, чтобы это понять, нужно было исследовать исходники. Побайтовое чтение файлов — редкая операция в мире Даже в том случае, если вы производите с файлом Для другой операции, нам понадобится четыре метода в классе работы с UTF (напоминаю, что константа ON этого класса определяет включена ли поддержка UTF): метод charset возвращает Замены очевидны: везде, где в коде встречается Потом нужно проверить все места, где встречаются вызовы chr и ord («egrep ’\\b(ord|chr)’ -R .») и проверить не нужно ли переписать После этого осталось только перекодировать исходный код: И базу: В процессе пуска проекта выяснилась ещё одна немаловажная подробность (спасибо Саше Покатилову): оказывается, несмотря на то, что установки локали (setlocale) никак не влияет на функции сортировки в PHP, она влияет на некоторые функции работы с файлами (dirname, basename и некоторые другие), вот цитата из описания функции dirname: dirname() is locale aware, so for it to see the correct directory name with multibyte character paths, the matching locale must be set using the setlocale() function. Поэтому не забывайте выставлять локаль, если пользуетесь этими функциями. Дополнено: внезапно нашлись неприятные грабли, будьте осторожны: функция preg_match_all (и preg_match) с ключём PREG_OFFSET_CAPTURE возвращает бинарное смещение в строке (т. е. указывающее не на байт, а на символ), даже Я поступил просто — написал простую функцию, которая корректирует выходные значения. Идея простая: отрезаем при помощи substr строку до смещения, потом измеряем её Еще позднее: оказывается и параметр offset (последний параметр в preg_match и preg_match_all) работает с бинарным смещением, И ещё позже: а вот вам ещё сюрприз: модуль Multibyte String считает, что кодировка И ещё сильно позже: strftime тоже использует локаль.Что же дальше?
# вот эти файлы перекодировать не надо, они у меня уже в UTF-8
SKIPIT='./php/Utf.php|./php/UtfReverseString.php|./php/UtfString.php'
tmp=`tempfile`
for line in $(find -name '*.php' -or -name '*.tpl' -or -name '*.inc' | egrep -v "$SKIPIT"); do
iconv -fcp1251 -tutf8 "$line" -o "$tmp"
[ -e "$tmp" ] && mv -f "$tmp" "$line"
donemysqldump -pпароль -uпользователь --add-drop-table --create-options --default-character-set=utf8 --order-by-primary -q база |
sed -e 's/cp1251;$/utf8;/mg' |
mysql -pпароль -uпользователь база
Комментарии 6
Я, наверное, пропустил, но будет ли этот код отправлен оригинальному PHP?
Спасибо! Место поправил, надеюсь, лучше стало.
Это же не патчи к PHP, так что нет.