PHP Classes and Objects Controlling Object Serialization

PHP Classes and Objects

Controlling Object Serialization

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.

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 the Solution 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. Because 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.Because you cannot pass arguments to __wakeUp(), it needs to get the filename fromsomewhere 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 singlerequest, or even continue to be used after it’s 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 becausethey take up too much disk space, or are calculated based on other data and should berecalculated or otherwise made fresh during object unserialization.That’s why the call to fclose() appears in the destructor and not in __sleep().