Posted by & filed under Programming.

Doctrine 2.0 documentation recommends against serializing entities. If you ignore the documentation, you will be faced with PHP notices, such as

Notice: Unknown: "id" returned as member variable from __sleep() but does not exist in Unknown on line 0

as well as broken object relations on unserialized objects. But its very tempting to use the entities in situations that implicitly require serialization – for example in Zend_Auth. A “User” entity used in Zend_Auth would be written to session, and thus serialized implicitly, creating the already mentioned problems.

However, its relatively easy to create a proxy to the entity. For example:


class UserProxy {
    protected $entity;
    protected $identity;
   
    public function __construct($entity)
    {
        $this->entity = $entity;
        // Get the identifier from the entity
        $this->identity = $this->entity->getId();
    }
   
    public function __call($name, $arguments)
    {
        return call_user_func_array(
            array($this->entity, $name),
            $arguments);
    }
   
    public function __sleep()
    {
        return array('identity');
    }
   
    public function __wakeup()
    {
        $this->restore();
    }
   
    protected function restore()
    {
        if (!empty($this->identity)) {
        // Replace with however you get
        // the entity manager
        $entityManager = Zend_Registry::get('em');
        $this->entity = $entityManager
            ->find('User', $this->identity);
    }
}

Now you just use the proxy in place of the entity in situations requiring serialization.


$toSerialize = new UserProxy($userEntity);

Any method calls made to the Proxy will be forwarded to the entity by the magic method. If the Proxy object is serialized, upon waking up, it will use the identifier to restore the entity.

Leave a Reply

  • (will not be published)