序列化/反序列化 PHP 对象

4
我有些困惑PHP中serialize/unserialize的概念。
假设我有一个非常简单的PHP对象(类someObject),并且在设置该对象的属性后,我想将其序列化:
所以我调用:serialize($someObject)
我想通过html表单将这个序列化的对象传递到另一个php脚本中,所以我把它设置为一个隐藏的值:
<input type="hidden" name="someObject" value="<? print $someObject; ?>"

在下一个php脚本中,我想使用unserialize来获取我的对象并将其转移到数据库中。
$unserialize = unserialize($_POST['someObject'])

但是这总是返回 BOOL(false) - 那我错过了什么呢?
谢谢你的帮助!

2
好的,使用 var_dump( $_POST['someObject'] ); 来查看。此外,您应该使用会话来处理此事,而不是隐藏输入字段。 - tereško
在第二个脚本中,$_POST['someObject'] 包含什么内容? - deceze
1
我不知道序列化字符串不包含 " 的任何保证,如果包含,生成的 HTML 将会损坏。如果 unserialize() 无法反序列化对象,它将返回 false - Joachim Isaksson
当我使用var_dump时,得到的结果是BOOL(false)。 - MrBr
2个回答

5

序列化字符串的格式如下:

O:1:"a":1:{s:3:"foo";s:3:"100";}

您需要对序列化字符串进行urlencode/urldecode处理,以防止序列化表示中的任何字符破坏您的标记。查看您的页面源代码。第一个引号很可能结束了您的HTML值属性。因此,您可能会得到以下内容:

<input ... value="O:1:"a":1:{s:3:"foo";s:3:"100";}">

所以你的 $_POST 永远不会包含完整序列化字符串,而只有 O:1:

如果这不是问题,确保你首先从对象中获取了序列化字符串。还请注意,某些对象不能被序列化或在(反)序列化时具有修改行为。有关详细信息,请参阅serialize 的 PHP 手册注释。

如果您不需要在运行 PHP 的不同服务器之间发送对象,请考虑将它们持久化在会话中。这更容易,更少出错,并且更安全,因为在传输过程中无法篡改对象。


@MrBr 嗯,是的。那是更明智的解决方案。 - Gordon

1

在反序列化对象之前,您需要在第二个脚本中定义类。


嗯,我不确定我是否理解正确,所以我使用类似$object = new someObject();这样的代码,然后稍后使用$unserialized = unserialize($_POST['someObject']); $object = $unserialized?但是在我的情况下,这也返回了FALSE。 - MrBr
嗯,你似乎混淆了定义类和实例化对象的概念... $object = new someObject() 是实例化一个对象... 在此之前,你必须已经定义了 someObject 类。反序列化一个序列化的对象将会创建该对象的实例,所以 $unserialized = unserialize($_POST['someObject']); 将会执行这个操作,在变量 $unserialized 中创建一个对象... $object = $unserialized; 将会创建 $unserialized 对象的一个克隆。请尝试准确定位错误发生的地方。 - Mark Baker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接