If you do turn on session.auto_start then you cannot put objects into your sessions since the class definition has to be loaded before starting the session in order to recreate the objects in your session.
This also applies if you use session_start() but did not load all classes that have been put into the session in earlier requests. This can result in problems if you have a very lazy class loading and do not want to use the __autoload() feature. In Stubbles we do not use __autoload() for several reasons, one of them is that we don't want PEARified class names in style of PACKAGE_SUBPACKAGE_ABSTRACTCLASS_CONCRETEIMPLEMENTATION. I simply don't like them, its one of the reasons why I choose SimpleTest over PHPUnit. But when there is no __autoload(), how could lazy loading work?
A decision made earlier was to have a basic interface for all our classes, called stubObject. Every class implements this interface (of course there is a default implementation). The trick is done with an additional class, which represents a serialized state of the concrete class. Every stubObject offers a getSerialized() method which returns a stubSerializedObject. This contains the full qualified classname and a serialized representation of the stubObject. It also features a getUnserialized() method which will load the class if it has not been loaded yet and then unserializes the stubObject .
Because the stubSerializedObject is always loaded in Stubbles our session implementation can now check if a value to store is an instance of stubObject. If it is, it just stores the return value of its getSerialized() method. On a later request, when the value should be retrieved from the session, the session checks if the instance to return is of type stubSerializedObject - if this is the case it returns the return value of its getUnserialized() method which loads the required class if this has not been done yet.
This approach seems to me even better than using __autoload(): it will load the required classes only if they are really used. If they are stored within the session but the current request does not use it the appropriate class will not be loaded. Very lazy, isn't it?
Some remarks to serialization without pity
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
Weblog: Stubblog Tracked: Mar 21, 01:29
WIRTW (What I Read This Week)
__autoload, serialization, etc.
Weblog: Darian Anthony Patrick Tracked: Apr 01, 18:20
Maybe got got Frank wrong. He is not storing a string in the session, but still an object. But all objects are instances of the stubSerializedObject class. These instances contain a serialized string representation of the original object plus the information, where the class can be found. So it's different from the old approach that suffered from the same problem as the standard PHP sessions, where you always need to know, what kind of objects are stored in the session before you get them from the session.
No, I did not. As far as I can see it would not help us because the callback only gets the classname, but that does not help us in finding the correct file for this class where we need the full qualified classname.
I don't know where it is written in stone that you have to use PEARified naming conventions in order to take advantage of __autoload(). It's just that PEARified conventions make finding the right class easier.
ini_set('unserialize_callback_func','__autoload') covers the other case.
How do you find the correct class to load then? When you only have the classname you either have to store all classes in the same directory without subdirectories, or have an array with those classnames as key and the filename as value in order (the ez-way). Both ways don't look very appealing to me.