Буквы И ш mysql и кодировки сp1251 и utf8

13 Лют
2009

Случился этот бред на mysql сервере 5й версии. Установленная на клиента групповая квота (включая базу данных) переполнилась таблицей сессий CakePHP

core.php

Configure::write(‘Session.save’, ‘php’);

было

Configure::write(‘Session.save’, ‘database’);

Configure::write(‘Session.start’, false);

было

Configure::write(‘Session.start’, true);

итого таблица cake_sessions за почти 2 года выросла до 90Мб, и никогда не очищалась. Но это фигня, дальше больше – при заполнении квоты крешнулась эта самая таблица, попытки ее реанимировать myisamchk-ом удались, но теперь таблицы с контентом не могут прочекаться, и самое печальное – бекапы mysqldump-ом сделанные за последние 2 недели пустые, есть месячной давности. Ладно, контент там не особо меняют, лишь бы сайт починить. Поскольку сдампить базу в текущем состоянии невозможно – удаляю все таблицы, и накатываю дамп месячной давности, последний из успешных. В итоге на сайте символ “ш” везде отображается как �?, аналогично “И”.

База данных создана с сравнением cp1251_general_ci, таблицы контента создавались без указания кодировки и тоже стали cp1251, CakePHP при работе не устанавливал сравнение и писал данные в utf8, в итоге данные требуют конвертации, которой я и занимался несколько дней. На всяк случай – что делать описываю ниже, может еще пригодится.

Для начала заменим в дампе битые символы чем-то более осмысленным, я это делал в текстовом редаторе – можно сделать проход по файлу php скриптом с заменой:

ш    С?    ш
И    Р?    И

$str=str_replace(“И”,”И”,$str);
$str=str_replace(“ш”,”ш”,$str);

Теперь по всем таблицам, где есть данные с битой кодировкой в записимости от типа данных сначала переводим поле в бинарный вид (blob), потом в оригинальный формат но уже в кодировке utf8. Таблицы и поля у Вас естественно будут отличаться от примера:

ALTER TABLE `pages` CHANGE `title` `title` BLOB;
ALTER TABLE `pages` CHANGE `title` `title` VARCHAR( 255 ) CHARACTER SET utf8;
ALTER TABLE `pages` CHANGE `content` `content` BLOB;
ALTER TABLE `pages` CHANGE `content` `content` text CHARACTER SET utf8;

1 Response to Буквы И ш mysql и кодировки сp1251 и utf8

Avatar

iMaxest

14 Вересня, 2011 at 12:09

В своё время намучился с этой проблемой, так как у нас все сайты многоязычные, и поэтому всегда используется уникод. И если с европейскими хостингами никогда не возникало проблем, то с российскими – постоянно. Итак, решение малой ш и большой И в правильной подборке сопоставлений на разных уровнях:
1. хост – utf8_general_ci
2. база данных – utf8_general_ci
3. таблица – utf8_general_ci
4. поля таблицы, в которых предполагается наличие кирилицы – cp1251_general_ci

При такой структуре сопоставлений проблема малой ш и большой И ликвидируется полностью. Не пугайтесь, что в полях таблицы с сопоставлением cp1251 через phpMyAdmin двины каракули вместо кириллического текста: в админке и на сайте всё будет отображаться корректно (при условии что они кодируют в UTF-8, естественно).

Comment Form

top