Простой способ преобразования сериализованных строк PHP в UTF8? - PullRequest
3 голосов
/ 09 января 2011

Я пытаюсь преобразовать греческую базу данных в utf8.На данный момент я выяснил, как это сделать (через MySQL, а не через функцию iconv ()), но у меня есть проблема: приложение хранит много данных в базе данных в сериализованном формате php (через serialize ()).

Как вы, возможно, знаете, этот формат хранит длины строк в сериализованной строке.Это означает, что, поскольку длины изменяются после преобразования (поскольку php5 не поддерживает Юникод должным образом), эти строки больше не могут быть сериализованы.

Пока что я рассматриваю возможность использования одного из следующих подходов для работывокруг этого:

  1. Используйте PHP для преобразования этих строк в utf8, и вместо преобразования всей сериализованной строки отмените ее сериализацию и преобразуйте каждый элемент в массиве.
  2. Напишите скрипт дляпересчитайте длину сериализованных строк.

Вариант № 2 кажется более простым, но я думаю, что должен быть более быстрый способ сделать это.Возможно, даже свободно доступный скрипт для их преобразования, поскольку я определенно не первый, кто сталкивается с этой проблемой.Есть идеи?

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 09 января 2011

Сделайте SHOW CREATE TABLE и проверьте кодировку TABLE. Затем подключитесь к базе данных с той же кодировкой (выполните USE «эту кодировку»;).

Теперь, когда вы получаете сериализованную строку, unserialize () ее. Возврат будет тем, что ваше приложение передало для serialize ().

Когда вы попадете сюда, вам нужно будет знать, какая кодировка строк была вставлена ​​изначально (например, ISO-8859-1, CP1252 и т. Д.), Чтобы вы могли преобразовать ее в utf-8.

Теперь, когда ваш греческий, без каламбура, преобразован в строку utf-8, вы можете поместить его обратно в базу данных.

Я настоятельно рекомендую вам реорганизовать базу данных, чтобы НЕ использовать сериализованные строки для хранения данных. Если вы храните BLOB-файлы в своей базе данных, рассмотрите возможность их удаления из базы данных и сохранения в вашей файловой системе.

Удачи.

0 голосов
/ 06 ноября 2013

Вот конкретный код для этого. Просто введите свои настройки / код в ключевые слова TODO:

//TODO: insert your settings here
$database = 'your_db_name';
$table = 'your_table_name';
$column = 'column_that_needs_conversion';
$primarykey = 'name_of_primary_key_in_that_table';

if (mb_internal_encoding() != 'UTF-8') {
    die('This script must be run in an UTF-8 environment!');
}

$utf8_encode_callback = create_function('&$item,$key', 'if (is_string($item)) $item = utf8_encode($item);');

$tablecol = $table .'.'. $column;
$getvaluesSQL = "SELECT ". $tablecol ." AS thevalue, ". $primarykey ." AS primkey FROM ". $database .".". $table ." WHERE ". $tablecol ." IS NOT NULL AND LENGTH(". $tablecol .") > 0";

//TODO: insert code here for executing $getvaluesSQL against your database

if (mysqli_num_rows($db_getvalues) > 0) {
    while ($getvalues = mysqli_fetch_assoc($db_getvalues)) {
        $php = unserialize(utf8_decode($getvalues['thevalue']));

        if (is_array($php)) {
            array_walk_recursive($php, $utf8_encode_callback);
        } elseif (is_string($php)) {
            $php = utf8_encode($php);
        }

        $new_ser = serialize($php);

        # For checking that conversion happened correctly (compare the two files):
        #file_put_contents('c:/dump0.txt', $getvalues['thevalue'] ."\r\n", FILE_APPEND);
        #file_put_contents('c:/dump1.txt', $new_ser ."\r\n", FILE_APPEND);

        $sql = "UPDATE ". $database .".". $table ." SET ". $tablecol ." = '". sql_esc($new_ser) ."' WHERE ". $primarykey ." = ". $getvalues['primkey'];

        //TODO: insert code here for executing $sql against your database

    }
}
echo '<div>Done with '. $tablecol .'</div>';
0 голосов
/ 09 января 2011

опция # 1 звучит намного проще и менее подвержена ошибкам.

Вы, вероятно, можете просто отменить сериализацию, а затем использовать array_walk_recursive () для преобразования каждой строки

...