什么可能导致 PHP 序列化函数失败?
我有一些服务器端 PHP 代码,尝试将数据对象(本质上是多维数组)保存到后端数据库。该数据对象最初作为从 Flex 应用程序发送的 AMF 动作脚本对象出现。我想保留整个对象以供以后使用,因此我使用了 php 序列化函数并将对象编码为一个可以进入数据库字段的简单字符串。代码如下所示:
$serializedDataObject = base64_encode(serialize($objectInstance->myDataObject));
当我想要恢复该对象并将其带回来时,我只需运行相反的操作
$unserializedDatanObject = unserialize(base64_decode($serializedDataObject));
到目前为止,这似乎运行良好。但有时我的 php 脚本会失败。我认为序列化步骤失败了。我的问题是从理论上讲什么可能导致 php 序列化和编码过程失败?数据对象数组中是否存在某些可能导致序列化失败的字符或数据类型?
在尝试序列化数据对象之前,是否需要对数据对象进行一些处理?
编辑:
为了澄清这个过程是这样工作的,
我有一个 Flex/Actionscript 客户端应用程序,它将基于 AMF 的 Actionscript 对象发送到服务器。在 PHP 方面,我使用 Zend AMF 库来读取 AMF 数据。该对象可以在 PHP 中检查,基本上看起来像一个关联的多维数组。此时,我尝试对对象进行序列化和 Base 64 编码,以便可以将对象作为编码字符串持久保存到数据库中。
希望这是有道理的。该问题是间歇性的,并且不容易持续重现。如果我能得到一些具体的错误消息,我会将它们发布在这里以供进一步说明。但现在我只是想知道序列化有什么限制来帮助我进一步调试。
I have some serverside PHP code that attempts persist a data object (essentially an multi-dimensional array) to a backend database. This data object originally comes in as AMF actionscript object sent from a flex application. I want persist the object in whole for later use so I have used the php serialize function and encode the object down a simple string that can go into a database field. The code looks like this:
$serializedDataObject = base64_encode(serialize($objectInstance->myDataObject));
When I want to revivify this object and bring it back I simply run the reverse
$unserializedDatanObject = unserialize(base64_decode($serializedDataObject));
So far this seems to work well. But sometimes my php script fails. I think it is failing at the serialization step. My question is theoretically speaking what could cause a php serialization and encoding process to fail? Are there certain characters or kinds of data in the data object array that could cause the serialization to bork?
Do I need to do some massaging of the data object before I try to serialize it?
Edit:
To clarify the process works like this
I have a Flex/Actionscript client app that sends AMF based actionscript objects to the server. On the PHP side I am using the Zend AMF library to read the AMF data. The object can be inspected in PHP and basically looks like an associative multi-dimensional array. It is at this point that I attempt to serialize and base 64 encode the object so that I can persist the object to the database as a encoded string.
Hopefully this makes sense. The problem is intermittent and not so easy to reproduce consistently. If I can get some specific error messages I will post them here for further clarification. But for now I was just wondering what are the limits of serialization to help me further debug.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
资源无法序列化,这可能是问题所在。避免此问题的一种方法是使用魔术方法:
__sleep
和__wakeup
。基本上,你的 __sleep 函数在你调用序列化时被调用,而 __wakeup 是在你反序列化时调用的,所以说它是一个数据库连接:在 sleep() 中关闭连接并存储某处的连接字符串(也许),并在唤醒时重新连接。
Resources can't be serialized which might be the problem. A way to avoid this problem is to use the magic methods:
__sleep
and__wakeup
.Basically, your
__sleep
function is called when you call serialize, and__wakeup
is for when you unserialize, so say it's a database connection: in sleep() close the connection and store the connection string somewhere (perhaps), and in wakeup, reconnect.@Greg 是正确的,因为您无法序列化资源。
鉴于您将对象描述为“数据对象”,我感觉它们包含您的数据库连接资源? (例如
$object->rs = mysql_connect(...);
)。如果是这样,请考虑使用
__sleep数据对象中的 ()
和__wakeup()
函数(__sleep()
在序列化之前立即调用,__wakeup()< /code> 反序列化后立即)。
__sleep()
函数应关闭所有数据库或文件资源,而__wakeup()
函数应重新连接到数据库。我上面链接的 PHP 手册条目有一个管理可序列化数据库连接的类的示例:
@Greg is correct in that you cannot serialize resources.
Given that you describe your objects as "Data objects" I have a feeling that they contain your database connection resources? (e.g.
$object->rs = mysql_connect(...);
).If so, consider using
__sleep()
and__wakeup()
functions in your data objects (__sleep()
is called immediately before serialization,__wakeup()
immediately after de-serialization).The
__sleep()
function should close any database or file resources while the__wakeup()
function should reconnect to the database.The PHP manual entry I linked above has an example of a class that manages a DB connection that is serializeable:
您无法正确序列化资源,例如文件句柄或数据库连接。
您也不能序列化内置的 PHP 对象,尽管我不太确定它涵盖了什么。
You can't properly serialize resources, such as file handles or database connections.
You also can't serialize built-in PHP objects, though I'm not exactly sure what that covers.
在 php.net/bas64_decode 上有一些提到大字符串不能很好地解码。此外,如果对象中存在不受支持的字符格式,则可能会导致问题。
On php.net/bas64_decode there is some mention of large strings not decoding well. Also, if you have unsupported character formats in the object it may cause problems.
这件事必须和汤姆一起去;引用 php.net/serialize:
就标准对象而言,您不应该有问题。记录您在 base64_encoding/decoding 后获得的数据,然后使用以下行检查您的数据。
Gotta go with Tom on this one; to quote php.net/serialize:
As far as standard objects are concerned you shouldn't have a problem. Log the data you're getting after base64_encoding/decoding, then use the following line to check your data.
您是否将序列化数据存储在数据库中?如果是,该字段是否足够大以容纳数据? Base64 编码使字符串长度增加约 1.3 倍,在某些数据库系统上会被截断。
Are you storing the serialized data inside a database? If so, is the field large enough to hold the data? Base64 encoding adds about 1.3 times to the length of the string which would be truncated on some DB systems.