2

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

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

4

2 回答 2

1

两个缺失的字符是用于受保护属性的空字节。你看不到它们,但它们仍然存在。因此,您$string的序列化不是有效的。

更新:

实际上,在 UTF-8 编码中可以使空字节可见(使用无效字符符号)。如果您选择输出,您可以在此演示中看到它: Textbox

string(40) "O:6:"Object":1:{s:11:"�*�variable";b:1;}"
于 2013-03-22T16:38:32.470 回答
1

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

于 2013-03-22T16:42:57.183 回答