我有一个网站,我想从 ISO 迁移到 UTF-8 。
我在数据库中有一条记录,该记录由以下主键索引:
s:22:"Informations générales";
问题是,现在(使用UTF-8),当我序列化字符串时,我得到:
s:24:"Informations générales";
(注意字符串的大小现在是字节数,而不是字符串长度)
所以这与非utf8以前的记录不兼容!
我做错了什么吗?我怎么能解决这个问题?
由于
答案 0 :(得分:4)
将数据库转储到latin1。
在命令行中:
sed -e 's/latin1/utf8/g' -i ./DBNAME.sql
以UTF-8导入转换为新数据库的文件。
使用php脚本更新每个字段。 进行查询,遍历每个字段并使用以下命令更新序列化字符串:
$str = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $str);
之后,我能够使用unserialize()以及使用UTF-8的所有内容。
答案 1 :(得分:2)
行为完全正确。具有不同编码的两个字符串将生成不同的字节流,从而生成不同的序列化字符串。
答案 2 :(得分:1)
PHP 4和5没有内置的Unicode支持;我相信PHP 6开始添加更多的Unicode支持,虽然我不确定它有多完整。
答案 3 :(得分:1)
要反序列化utf-8编码的序列化数组:
$array = @unserialize($arrayFromDatabase);
if ($array === false) {
$array = @unserialize(utf8_decode($arrayFromDatabase)); //decode first
$array = array_map('utf8_encode', $array ); // encode the array again
}
答案 4 :(得分:0)
你没有做错任何事。 v6之前的PHP只是不支持Unicode,因此如果您没有支持它(例如,通过mbstring
扩展或其他方式),则不支持它。
我们在serialize()
附近编写了自己的包装来解决这个问题。您也可以转向其他序列化技术,例如JSON(自5.2.0以来在PHP中使用json_encode()
和json_decode()
)。