Terry Chay made some remarks to
my last blog entry about a solution for lazy class loading without using __autoload(). Some of his statements seem like I explained my implementation not good enough leading to wrong interpretations. In this blog entry I'll use some of his statements to take a deeper look into my implementation and show that he has drawed some conclusions which I want to disprove.
He writes:
Frank makes his classes that need to be serialized implement an interface (technically, it is subclassed from his base object). This object has a method (not __sleep) that serializes itself into a special object containing this data along with a string containing the class path. This object is included before session_start and reads the full path name to include the class definition just in time.
This approach violates my central tenet of looking for solutions in practices or functions. He closes himself off to built-in functions of __sleep() and __wakeup() because he is no longer serializing the class itself, he’s serializing a stub object.
That is not correct. To show this I will dig into some technical details of my
implementation:
class stubSerializedObject implements stubObject
{
/**
* full qualified class name of the serialized class
*
* @var string
*/
protected $className;
[...]
/**
* the serialized class data
*
* @var string
*/
protected $data;
/**
* constructor
*
* @param stubObject $object the stubObject instance to serialize
*/
public function __construct(stubObject $object)
{
$this->className = $object->getClassName();
$this->hashCode = $object->hashCode();
$this->data = serialize($object);
}
[... rest of class ...]
I have marked the important line. It shows that the object itself is serialized which means that one can still use __sleep() and __wakeup() within the class to serialize. Obviously, there is no parallel architecture for serialization and deserialization, its just wrapped.
You can’t use two frameworks, because in this case they would have conflicting ways of deserializing themselves. If you wanted to use a library from PEAR, you’d be forced to put an adapter pattern in front of it just to get the fucker to serialize.
As it should become clear from what I explained above you can still put any other classes you use (maybe those from PEAR) into the session without worrying about how they should be serialized - it just uses the default serialization mechanism.
$session->putValue('stubblesClass', $stubblesClass);
$session->putValue('PEAR_Example_Class', $pearExampleClass);
No need to have an adapter.

Our session implementation takes care of the correct handling. And no problem if you use another session class from another framework: in this case you just can't make use of the lazy loading, but still put the object into the session as you do with any other one.
More to the point, not storing classpaths with the serialized object is a Good Thing™. Since the session is most-likely stored across servers (via the memcache best practice), storing class paths with the sessions means the directory architecture has to be shared across servers.
Well, not the whole classpath is stored. Our class loader knows where the classes reside. The "class path" is just the path from there to the correct subdirectory containing the file with the class. Therefore the directory structure can be different on another server, it is just required that the directory structure of your source directory is the same, but the path to the source directory can be different on each server. So there is nowhere a hard path, the stored class path is just a relative one.