заметки на полях

Блокнот разработчика

Перевод сайта c cp1251 на UTF-8

Для начала перевести БД из cp1251 в utf8.
Сделать дамп mysqldump -u svd -n --skip-opt --skip-set-charset --triggers --disable-keys svdev > dump.sql – получится чистый дамп без упаминания кодировок, можно получить отдельно данные: mysqldump -u svd -nt --skip-opt --skip-set-charset --disable-keys svdev > data.sql, поменять кодировку полей в схеме, вместо:

name varchar(64) character SET cp1251 NOT NULL

сделать

name varchar(64) character SET utf8 NOT NULL

или же убрать упоминание кодировки из полей вовсе:

name varchar(64) NOT NULL

так как при установке правильной кодировки для БД кодировки для текстовых полей создаваемых таблиц будут устанавливаться верно сами, затем изменить кодировку самой БД:

ALTER DATABASE svdev DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci

и залить назад в обратном порядке – сначала структуру, затем данные.
Следующим шагом необходимо изменить кодировку файлов, для этого я набросал простенький скрипт (подключаемые библиотеки которые трогать не надо – типа tiny просто вынес сначала из проекта, а затем вернул обратно:

#!/bin/sh
for FILE in `find /var/www/svdev/ | egrep -i "\.(php|html)$"`
do
iconv -f cp1251 -t utf8 $FILE > $FILE".utf"
mv -f $FILE".utf" $FILE
echo $FILE" - work complete"
done

Он в заданной директории файлы по маске .php и .html перекодирует в UTF используя утилиту iconv во временный файл, а затем перезаписывает исходный файл временным.
Следующим шагом убедимся в правильной настройке mb_ функций PHP. Для этого создадим файлик vim strtest.php и положим в него следующее содержимое:

<?
echo strlen("мама мыла раму") . "\n";
echo mb_strlen("мама мыла раму") . "\n";
echo mb_strlen("мама мыла раму", "UTF-8");
?>

Правильная длина строки – 14 символов. Выполним его из консоли: php5-cgi strtest.php В начале у меня получилось следующее:

X-Powered-By: PHP/5.2.10-2ubuntu6.3
Content-type: text/html

26
26
14

Для исправления – установим верные значения в /etc/php5/cgi/php.ini и /etc/php5/cli/php.ini, для этого по файлу надо поискать encoding и charset
Нашлись следующие параметры:

default_charset = "UTF-8"
...
mbstring.language = Russian
mbstring.internal_encoding = UTF-8

Теперь при повторном выполнении теста php5-cgi strtest.php второе значение без указания кодировки должно совпасть с первым и появиться кодировка по умолчанию:

X-Powered-By: PHP/5.2.10-2ubuntu6.3
Content-type: text/html; charset=UTF-8

26
14
14

Так же не лишним будет в конфиге проекта указать верно локаль, к примеру setlocale(LC_ALL, "ru_RU.utf8"); список доступных локалей в системе можно посмотреть locale -a (ну и на всякий случай проверить что с новой локалью не будет багов, подробнее здесь: Как float зависит от локали?! )
Указать кодировку в настройках nginx для нужного сайта /etc/nginx/sites-available/svdev:

server {
...
        charset         UTF-8;
        source_charset  UTF-8;
...
}

Ну и самая нудная часть – пройтись по проекту и заменить функции работы со строками на их mb_ аналоги, в используемые регулярные выражения добавить модификатор u и если отправляются где-то письма – изменить кодировку писем.
Ну вот вроде и все! Перед всеми манипуляциями неплохо бы сделать резервную копию файлов и БД, на всякий случай.

Дополнительное чтиво

Tags: ,

Leave a Reply