3

我正在尝试将希腊数据库转换为 utf8。至此,我已经弄清楚了如何做到这一点(通过 MySQL,而不是通过 iconv() 函数)但我有一个问题:应用程序以 php 序列化格式将大量数据存储在数据库中(通过 serialize()) .

您可能知道,这种格式将字符串长度存储在序列化字符串中。这意味着由于转换后长度发生了变化(因为 php5 不正确支持 Unicode),这些字符串不能再被反序列化。

到目前为止,我正在考虑使用以下方法之一来解决这个问题:

  1. 使用 PHP 将这些字符串转换为 utf8,而不是转换整个序列化字符串,反序列化它并转换数组中的每个项目。
  2. 编写一个脚本来重新计算序列化字符串的长度。

选项#2 似乎更容易,但我认为必须有一种更快的方法来做到这一点。甚至可能是用于转换它们的免费脚本,因为我绝对不是第一个面临这个问题的人。有任何想法吗?

提前致谢。

4

3 回答 3

1

执行 SHOW CREATE TABLE 并检查 TABLE 的编码。然后使用相同的编码连接到数据库(执行 USE 'that encoding';)。

现在,当您检索序列化字符串 unserialize() 时。返回将是您的应用程序传递给 serialize() 的任何内容。

到达这里后,您需要知道最初插入字符串的编码是什么(例如 ISO-8859-1、CP1252 等...),以便将其转换为 utf-8。

现在您已经将希腊语(没有双关语)转换为 utf-8 字符串,您可以将其放回数据库中。

我强烈建议您重新组织数据库以不使用序列化字符串来存储数据。如果您将 BLOBS 存储在数据库中,请考虑将它们移出数据库并将它们存储在文件系统中。

祝你好运。

于 2011-01-09T19:44:27.173 回答
0

选项#1听起来更容易,而且对我来说更不容易出错。

您可能只是反序列化,然后使用 array_walk_recursive() 对每个字符串进行转换

于 2011-01-09T19:30:14.417 回答
0

这是执行此操作的特定代码。只需在 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>';
于 2013-11-06T12:11:26.527 回答