Буквы И ш 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. Таблицы и поля у Вас естественно будут отличаться от примера:

1
2
3
4
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