Recipe 7.18. Controlling Object Serialization


7.18.1. Problem

You want to control how an object behaves when you serialize( ) and unserialize( ) it. This is useful when you need to establish and close connections to remote resources, such as databases, files, and web services.

7.18.2. Solution

Define the magical methods __sleep( ) and __wakeUp( ), as shown in Example 7-38.

Controlling serialization using __sleep( ) and __wakeUp( )

<?php class LogFile {     protected $filename;     protected $handle;     public function __construct($filename) {         $this->filename = $filename;         $this->open();     }     private function open() {         $this->handle = fopen($this->filename, 'a');     }     public function __destruct($filename) {         fclose($this->handle);     }     // called when object is serialized     // should return an array of object properties to serialize     public function __sleep() {         return array('filename');     }     // called when object is unserialized     public function __wakeUp() {         $this->open();     } } ?>

7.18.3. Discussion

When you serialize an object in PHP, it preserves all your object properties. However, this does not include connections or handles that you hold to outside resources, such as databases, files, and web services.

These must be reestablished when you unserialize the object, or the object will not behave correctly. You can do this explicitly within your code, but it's better to abstract this away and let PHP handle everything behind the scenes.

Do this through the __sleep( ) and __wakeUp( ) magic methods. When you call serialize( ) on a object, PHP invokes __sleep( ); when you unserialize( ) it, it calls __wakeUp( ).

The LogFile class in Example 7-38 has five simple methods. The constructor takes a filename and saves it for future access. The open( ) method opens this file and stores the file handle, which is closed in the object's destructor.

The __sleep( ) method returns an array of properties to store during object serialization. Since file handles aren't preserved across serializations, it only returns array('filename') because that's all you need to store.

That's why when the object is reserialized, you need to reopen the file. This is handled inside of __wakeUp( ), which calls the same open( ) method used by the constructor. Since you cannot pass arguments to __wakeUp( ), it needs to get the filename from somewhere else. Fortunately, it's able to access object properties, which is why the filename is saved there.

It's important to realize that the same instance can be serialized multiple times in a single request, or even continued to be used after its serialized. Therefore, you shouldn't do anything in __sleep( ) that could prevent either of these two actions. The __sleep( ) method should only be used to exclude properties that shouldn't be serialized because they take up too much disk space, or are calculated based on other data and should be recalculated or otherwise made fresh during object unserialization.

That's why the call to fclose( ) appears in the destructor and not in __sleep( ).

7.18.4. See Also

Documentation on magic methods at http://www.php.net/manual/en/language.oop5.magic.php; the unserialize( ) function at http://www.php.net/unserialize and the serialize( ) function is found at http://www.php.net/serialize .




PHP Cookbook, 2nd Edition
PHP Cookbook: Solutions and Examples for PHP Programmers
ISBN: 0596101015
EAN: 2147483647
Year: 2006
Pages: 445

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net