我正在尝试将希腊数据库转换为utf8。在这一点上,我已经想出了如何做到这一点(通过MySQL,而不是通过iconv()函数),但我遇到了一个问题:应用程序以php序列化格式在数据库中存储大量数据(通过serialize())
您可能知道,此格式将字符串长度存储在序列化字符串中。这意味着由于转换后长度发生了变化(因为php5不能正确支持Unicode),所以这些字符串不能再被反序列化了。
到目前为止,我正在考虑使用以下方法之一来解决这个问题:
选项#2似乎更容易,但我认为必须有一个更快的方法来做到这一点。也许甚至是一个免费提供的脚本来转换它们,因为我绝对不是第一个面对这个问题的人。有什么想法吗?
提前致谢。
答案 0 :(得分:1)
执行SHOW CREATE TABLE并检查TABLE的编码。然后使用相同的编码连接到数据库(执行USE'即编码';)。
现在当你检索序列化字符串unserialize()时。返回将是您的应用程序传递给serialize()的任何内容。
到达此处后,您需要知道最初插入的字符串的编码方式(例如ISO-8859-1,CP1252等...),因此您可以将其转换为utf-8。
现在您已经将希腊语,没有双关语言转换为utf-8字符串,您可以将其放回数据库中。
我强烈建议您重新组织数据库,以便不使用序列化字符串来存储数据。如果要将BLOBS存储在数据库中,请考虑将它们移出数据库并将其存储在文件系统中。
祝你好运。答案 1 :(得分:0)
选项#1听起来更容易,而且更不容易出错。
你可能只是反序列化,然后使用array_walk_recursive()对每个字符串进行转换
答案 2 :(得分: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>';