What could cause a failure in PHP serialize function?

我们两清 提交于 2019-12-11 03:30:12

问题


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.


回答1:


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.




回答2:


@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
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();
    }
}



回答3:


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.




回答4:


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.

  1. Make sure that you don't have any unsupported character formats in your objects
  2. Try and log how big the objects are that are being serialized



回答5:


Gotta go with Tom on this one; to quote php.net/serialize:

The value to be serialized. serialize() handles all types, except the resource-type. You can even serialize() arrays that contain references to itself. Circular references inside the array/object you are serializing will also be stored. Any other reference will be lost.

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.

echo '<pre>'; print_r($decodedObject); echo '</pre>';



回答6:


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.



来源:https://stackoverflow.com/questions/1341494/what-could-cause-a-failure-in-php-serialize-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!