保存状态生成通知“偏移时出错”

时间:2013-03-22 16:33:55

标签: php serialization

我正在尝试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

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

2 个答案:

答案 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而不是字符数据。