保存状态在偏移处产生通知“错误”


Saved state generates notice "error at offset"

我正在尝试unserialize一个对象的保存实例状态,但我的serialized对象不能恢复由于"错误在偏移"错误。

这适用于我试图反序列化的所有对象,即使是最简单的对象。

class Object
{
    protected $variable = true;
}
$object = serialize(new Object());
$string = 'O:6:"Object":1:{s:11:"*variable";b:1;}';
echo $object."'n";
echo "length: ". strlen($object)."'n'n";
echo $string . "'n"; // Strangely 2 characters shorter than $object
echo "length: ". strlen($string)."'n";
unserialize($object); // Works
unserialize($string); // Does not work

这段代码输出:

O:6:"Object":1:{s:11:"*variable";b:1;}
length: 40 
O:6:"Object":1:{s:11:"*variable";b:1;} 
length: 38 
Notice: unserialize(): Error at offset 33 of 38 bytes

我卡住了,为什么我不能反序列化保存的字符串?

缺少的两个字符是用于protected属性的空字节。你不能看到它们,但它们仍然在那里。因此,你的$string不是一个有效的序列化。

更新:

实际上,在UTF-8编码中可以使空字节可见(使用无效的字符符号)。你可以在这个演示中看到,如果你选择输出:文本框

string(40) "O:6:"Object":1:{s:11:"�*�variable";b:1;}"

* ("'x2A")实际上被2个不可见的空字节("'x0'x2A'x0")终止。这意味着您必须将其视为BINARY(这也意味着在数据库中存储BINARY/BLOB列而不是CHAR/TEXT列)。这个故事的寓意是:PHP保留随时更改序列化方法的权利,所以不要使用PHP以外的任何东西来序列化字符串,并且将序列化的字符串视为二进制而不是字符数据