Caching Objects in PHP5

Last Friday I set out to implement object caching on a project I am working on. I ran into a couple of stumbling blocks and thought I would share my findings while the PHP5 docs catch up.


I am caching serialized objects to both the session as well as to the file system using PEAR::Cache_Lite. Caching to the session is particularly cool because once you register an object to the session, that object is updated at the end of every request. I am finding this can be great for user auth/perms data objects. Caching to the file system is something I hope to implement on this blog (among other places). With file-system caching, the cached objects die after not being used for a configurable amount of time. This makes a lot of sense for blog postings.

__sleep()
The first gotcha that I ran into is that there MUST be a __sleep() method defined for the object you are hoping to cache.
This is actually true for any object you want to serialize which is the first step to caching. I am pretty sure this method can be inherited, but there is not one defined by default. There was a second little gotcha that I found with the sleep method. The __sleep() method must return a flat array of the properties whose values you want to cache. This array should not include the values of those properties. As with earlier versions of PHP, resources (db connection, file, etc) are not cached.

__wakeup()
This isn’t much of a gotcha, but it should be mentioned here. The __wakeup() method is not required, but if defined it will be called when an object is unserialized. This allows you to put resources back in place before the object is used. I think that this method should return void.

example caching objects in the session


<?php

// classes must be defined before they are unserialized
// for objects that are cached in the session this means
// they must be required before the session is started on
// a request
require_once('DataObject/User.php');

session_start();

// create the user dataobject if it does not exist.
if (!isset($_SESSION['user'])) {
    $user = new DataObject_User();
    session_register($user);
}

// snippets from the DataObject_User class
class DataObject_User extends DataObject {

    // caches the values
    __sleep() {
        return array('username','user_id','password','email');
    }

    // restarts the database connection resource
    __wakeup() {
        $this->db = DB::Connect($this->dsn);
    }
}
?>

example caching objects with PEAR::Cache_Lite


<?php

require_once('Cache/Lite.php');

$options = array(
    'cacheDir' => '/tmp/',
    'lifeTime' => 3600
);

// Create a Cache_Lite object
$Cache_Lite = new Cache_Lite($options);

if ($obj = $Cache_Lite->get($id)) {
    $user = unserialize($obj);
}
else {
    $user = new DataObject_User();
}

// serialize the object and put it back in the cache
$obj = serialize($user);
$Cache_Lite->save($obj);
?>

Of course there are more ways to do it than this, but this is how I am doing it now…

-Jackson

    None Found