+7 495 008 8452 пн.-пт. 10:00 – 17:00
Если у вас возникли какие либо вопросы которые вы не смогли решить по нашим публикациям самостоятельно,
то ждем ваше обращение в нашей службе тех поддержки.


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

1. Сделайте резервную копию

До начала любых изменений сделайте резервную копию. Иначе в результате «лечения» все может стать намного хуже и безвозвратно.

2. Диагностируйте вид перекодировки

Сначала выясните, в какой именно кодировке наш «пациент». Для этого можно скопировать несколько фрагментов текста и проверить их «Декодером» студии Лебедева.

3. Сделаем функции для выявления «больных» участков текста

Чтобы не лечить здорового текста, надо отделять перекодированные фрагменты.

Для UTF-8 это будет выполнять такая функция:

<?
function good($str) {
    return preg_match('#[а-яА-Я]#u', $str);
}


А для cp1251 другая:

<?
function good($str) {
    $str = mb_convert_encoding($str, 'windows-1251', 'utf-8');
    return preg_match('#[а-яА-Я]#u', $str);
}


4. Код для «лечения»

Например, CP1252 преобразует в UTF-8 такой код:

<?
function heal($str) {
    $str = mb_convert_encoding($str, 'windows-1252', 'utf-8');
    if (good($str)) return $str;
    return false;
}


Осталось написать код, который обработает всю базу и выполнит нужную нам перекодировку. Вот он:

<?
$rs  = $DB->Query('show tables');
while ($f   = $rs->Fetch()) // таблицы
{
    list($k, $t)      = each($f);
    $rs0 = $DB->Query('show table status like "' . $t . '"');
    $f0  = $rs0->Fetch();
    if ($f0['Rows'] == 0) continue;
    $arCols = array();
    $id     = '';
    $rs0    = $DB->Query('show columns from ' . $t);
    while ($f0     = $rs0->Fetch()) // столбцы
    {
        if ($f0['Key'] == 'PRI') $id     = $f0['Field'];
        if (preg_match('#char|text#', $f0['Type'])) $arCols[]        = $f0['Field'];
    }
    if (!$id) {
        echo ('Нет поля ID: ' . $t . '<br>');
        continue;
    }
    if ($id == 'ID') continue;
    foreach ($arCols as $fld) {
        if (!$rs1 = $DB->Query('SELECT  `' . $id . '`,`' . $fld . '` FROM ' . $t)) {
            echo ('Нет поля ID: ' . $t . '<br>');
            break;
        }
        while ($f1  = $rs1->Fetch()) // строки
        {
            if (!$f1['ID']) if (!trim($f1[$fld])) continue;
            if ($new = heal($f1[$fld])) {
                $q   = 'UPDATE ' . $t . ' SET ' . $fld . '="' . $DB->ForSQL($new) . '" WHERE ' . $id . '="' . $DB->ForSQL($f1[$id]) . '"';
                $DB->Query($q);
                if ($yyy++ < 10) echo $q . '<br>';
            }
        }
    }
}
echo '$iii=' . $iii;


5. Готово!

-------------------------------
Спасибо за внимание!
Читайте свежий выпуск «Кладовки программиста» каждый день!

Назад в раздел

Подписаться на новые материалы раздела:














CAPTCHA