What can cause the PHP serialization function to fail?

I have some PHP code on the server that is trying to store a data object (essentially a multidimensional array) in a database. This data object originally comes in as an ActionScript AMF object posted from a flex application. I want to save the whole object for later use, so I used the php serialization function and encoded the object on a simple string that can get into a database field. The code looks like this:

$serializedDataObject = base64_encode(serialize($objectInstance->myDataObject));

      

When I want to animate this object and return it, I just run reverse

$unserializedDatanObject = unserialize(base64_decode($serializedDataObject));

      

So far this works well. But sometimes my php script fails. I think it doesn't work in the serialization step. My question is theoretically about what could be causing the php serialization and encoding process to fail? Are there specific characters or data types in the array of data objects that can cause serialization?

Do I need to massaging a data object before trying to serialize it?

Edit:

To clarify this process, follow these steps

I have a Flex / Actionscript client application that sends AMF based ActionScript objects to the server. On the PHP side, I am using the Zend AMF library to read AMF data. The object can be checked in PHP and basically looks like an associative multidimensional array. It is at this point that I am trying to serialize and base 64 object encoding so that I can store the object in the database as an encoded string.

Hope this makes sense. The problem is intermittent and not easy to reproduce consistently. If I can get some error messages, I'll post them here for further clarification. But for now I'm just wondering what serialization bounds help me debug.

+2


source to share


6 answers


Resources cannot be serialized, which can be a problem. The way to avoid this problem is to use magic methods: __sleep

and__wakeup

.



Basically, your function __sleep

gets called when you call serialize, and __wakeup

- when you unserialize, so say it is a database connection: in sleep () close the connection and save the connection string somewhere (maybe), and on wake up, reconnect.

+5


source


@Greg is correct in that you cannot serialize resources.

Given that you describe your objects as "data objects", I get the feeling that they contain resources to connect to the database? (for example $object->rs = mysql_connect(...);

).

If so, use and function in your data objects ( called right before serialization, right after de-serialization). __sleep()

__wakeup()

__sleep()

__wakeup()



The function __sleep()

must close any databases or file shares and the function __wakeup()

must reconnect to the database.

The above PHP link above contains an example of a class that manages a serializable DB connection:

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

      

+4


source


You cannot properly serialize resources such as file descriptors or database connections. You also cannot serialize built-in PHP objects, although I'm not entirely sure what this covers.

+3


source


There are some mentions in php.net/bas64_decode about large strings that don't decode well. Also, if you have unsupported character formats in the object, this can cause problems.

  • Make sure there are no unsupported character formats in your objects.
  • Try and write down how big are the objects that are serializable
+3


source


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

The value to serialize. serialize () handles all types except the resource type. You can even serialize () arrays containing references to themselves. It will also keep the circular references inside the array / object you are serializing. Any other link will be lost.

As far as standard objects go, you shouldn't have a problem. Register the data you get after base64_encoding / decoding, then use the following line to validate your data.

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

      

+1


source


Are you storing serialized data inside the database? If so, is the field large enough to hold the data? Base64 encoding adds about 1.3 times the length of the string, which will be truncated on some database systems.

+1


source







All Articles