PHP unserialize()奇怪的问题:偏移处的错误表示错误的偏移值?

时间:2014-01-12 08:27:06

标签: php serialization

我在unserialize()中遇到了这个奇怪的问题。我继续收到此错误:“注意:unserialize()[function.unserialize]:错误在偏移343405的769339字节...”

偏移343405是“p”(下面一行中“价格”的第一个字符):

";s:5:"price";s:6:"$60.83";

整个字符串非常大(1 MB),正在从服务器上的临时文件中读取LINK TO FILE

我花了四个多小时就已经花了四个多小时仍然无法弄清楚发生了什么,看来错误给出了不正确的偏移量。这可能吗?

这段代码并不新鲜,而且它已经为许多用户(不同的数据)工作而没有任何问题。 我生成了这样的序列化字符串:

htmlspecialchars(serialize($data));

我读它如下:

if (get_magic_quotes_gpc()) {
    $data = stripslashes($data);

    $data = unserialize(htmlspecialchars_decode($data));
}
else{
    $data = unserialize(htmlspecialchars_decode($data));
}

在这种特殊情况下,魔术引号已启用。

非常感谢任何见解。

2 个答案:

答案 0 :(得分:2)

处理多字节字符串似乎存在问题。尝试使用自定义反序列化函数来解决您的问题:

/**
 * Mulit-byte Unserialize
 *
 * UTF-8 will screw up a serialized string
 *
 * @access private
 * @param string
 * @return string
 */
function mb_unserialize($string) {
    $string = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $string);
    return unserialize($string);
}

此外,尝试设置mb_internal_encoding以确保正确设置内部字符编码:

mb_internal_encoding('utf-8');
$arr = array('foo' => 'bár');
$buf = serialize($arr);

答案 1 :(得分:0)

我找到了错误原因,但是没有解释通知中给出的错误偏移,所以我不会将此答案标记为已接受。

序列化字符串被破坏的原因是stripslashes()的使用。此脚本的旧版本通过POST请求发送序列化字符串,因此magic_quotes_gpc设置是相关的,因此是条件语句。现在,但序列化字符串被写入临时文件,然后该文件被另一个脚本读取,因此不使用魔术引号。