我正在尝试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
我被卡住了,为什么我不能反序列化已保存的字符串?
答案 0 :(得分:1)
两个缺少的字符是用于受保护属性的空字节。你不能看到他们但他们仍然在那里。因此,您的$string
不是有效的序列化。
实际上,可以使用UTF-8编码使空字节可见(使用无效字符符号)。如果您选择输出: 文本框
,您可以在this demo中看到它string(40) "O:6:"Object":1:{s:11:"�*�variable";b:1;}"
答案 1 :(得分:1)
*
("\x2A"
)实际上由2个不可见的空字节("\x0\x2A\x0"
)终止。这意味着您必须将其视为BINARY(这也意味着在数据库中存储在BINARY / BLOB列而不是CHAR / TEXT列中)。故事的道德是:PHP保留随时改变序列化方法的权利,所以不要使用任何东西但是要将序列化字符串串行化,并将序列化字符串视为BINARY而不是字符数据。