我有一些服务器端PHP代码尝试将数据对象(实质上是一个多维数组)持久存储到后端数据库。此数据对象最初是作为从Flex应用程序发送的AMF actionscript对象引入的。我想要将整个对象持久化以供以后使用,所以我使用了php serialize函数并将对象编码为一个可以进入数据库字段的简单字符串。代码如下所示:
$serializedDataObject = base64_encode(serialize($objectInstance->myDataObject));
当我想要恢复此对象并将其恢复时,我只需运行反向
$unserializedDatanObject = unserialize(base64_decode($serializedDataObject));
到目前为止,这似乎运作良好。但有时我的PHP脚本失败。我认为它在序列化步骤中失败了。从理论上讲,我的问题是什么可能导致php序列化和编码过程失败?数据对象数组中是否存在可能导致序列化为bork的某些字符或数据?
在尝试序列化之前,是否需要对数据对象进行一些按摩?
修改
澄清这个过程是这样的
我有一个Flex / Actionscript客户端应用程序,它将基于AMF的actionscript对象发送到服务器。在PHP方面,我使用Zend AMF库来读取AMF数据。该对象可以在PHP中检查,基本上看起来像一个关联的多维数组。正是在这一点上,我尝试序列化和基础64编码对象,以便我可以将对象作为编码字符串持久保存到数据库。
希望这是有道理的。这个问题是间歇性的,不容易一致地重现。如果我能得到一些具体的错误消息,我会在这里发布以便进一步说明。但是现在我只是想知道序列化的限制是什么,以帮助我进一步调试。
答案 0 :(得分:5)
资源无法序列化,这可能是问题所在。避免此问题的一种方法是使用魔术方法:__sleep
and __wakeup
。
基本上,当您调用serialize时调用__sleep
函数,而反序列化时调用__wakeup
,所以说它是数据库连接:在sleep()中关闭连接并存储连接字符串某处(也许),并在醒来时重新连接。
答案 1 :(得分:4)
@Greg是正确的,因为你无法序列化资源。
鉴于您将对象描述为“数据对象”,我觉得它们包含您的数据库连接资源? (例如$object->rs = mysql_connect(...);
)。
如果,请考虑在数据对象中使用__sleep()
and __wakeup()
函数(在序列化之前立即调用__sleep()
,在反序列化之后立即调用__wakeup()
。)< / p>
__sleep()
函数应关闭所有数据库或文件资源,而__wakeup()
函数应重新连接到数据库。
我上面链接的PHP手册条目有一个类的例子,它管理可序列化的数据库连接:
<?php
class Connection {
protected $link;
private $server, $username, $password, $db;
public function __construct($server, $username, $password, $db)
{
$this->server = $server;
$this->username = $username;
$this->password = $password;
$this->db = $db;
$this->connect();
}
private function connect()
{
$this->link = mysql_connect($this->server, $this->username, $this->password);
mysql_select_db($this->db, $this->link);
}
public function __sleep()
{
return array('server', 'username', 'password', 'db');
}
public function __wakeup()
{
$this->connect();
}
}
答案 2 :(得分:3)
您无法正确序列化资源,例如文件句柄或数据库连接。 你也无法序列化内置的PHP对象,虽然我不确定它涵盖了什么。
答案 3 :(得分:3)
在php.net/bas64_decode上有一些提到大字符串不能很好地解码。此外,如果对象中的字符格式不受支持,则可能会导致问题。
答案 4 :(得分:1)
要和汤姆一起去这个;引用php.net/serialize:
要序列化的值。 serialize()处理除resource-type之外的所有类型。您甚至可以序列化()包含对自身的引用的数组。您正在序列化的数组/对象内的循环引用也将被存储。任何其他参考将丢失。
就标准对象而言,您应该没有问题。记录base64_encoding / decoding之后获得的数据,然后使用以下行检查数据。
echo '<pre>'; print_r($decodedObject); echo '</pre>';
答案 5 :(得分:1)
您是否将序列化数据存储在数据库中?如果是这样,该字段是否足以容纳数据? Base64编码增加了大约1.3倍的字符串长度,这将在某些数据库系统上被截断。