April 15, 2009

inheritance and __autoload

Tags: , , , , , ,
Filed under: ZenMagick — DerManoMann @ 4:46 am

A while ago I wrote about the loader and how there were still a couple pieces missing to make loading really useful.

As it turns out PHP has an answer for my question and that is __autoload(). I’ve read a little bit about this special method [or hook if you like] but then forgot about it again. Having a better memory would have saved me a few hours, I guess ;)

The __autoload() function allows application code to make one final attempt at locating and loading unresolved classes/interfaces and functions. Adding this function with a simple call to the loader was all needed to make everyone happy and remove the need to call ZMLoader::resolve('CLASSNAME') to be able to safely use CLASSNAME.

However, things were not quite as easy. The loader uses a lot of class_exists() and such and (obviously) those trigger another call to __autoload()! So, I’ve rearranged the central code in ZMLoader again and actually it is a lot more readable now :) [and perhaps even a bit faster too!]

The most satisfying bit of the whole excercise was removing the code that preloads a range of classes to be able to use the service classes right away. Also, in places where explicitely classes with the ‘ZM‘ prefix are used it’s now possible to use PHP’s new operator rather than the more convulated ZMLoader::make('CLASSNAME');.

Perfomance doesn’t seem to have suffered from this change and in some case might even be better (at least when not using core.php). And while I was at it I added some simple stats to the loader and extended the zm_page_stats plugin to display those. It’s rather basic and consists just of the number of static and class/interface files loaded during a request. Still, interesting to compare different pages.

March 9, 2009

resolving inheritance

Tags: , , , , ,
Filed under: ZenMagick — DerManoMann @ 2:39 am

EDIT: This pose is thankfully obsolete due to the magic __autoload function!

So far all code [classes and interfaces in particular] in ZenMagick rely on the loader to ensure that extended classes and implemented interface used are loaded. So far this has worked quite well.

Reasons for doing this are:

  • Late binding of the actual implementation of classes
  • Having a central place that handles file loading
  • In case core.php is used (merging all code into a single, stripped file) all that is not necessary

Obviously, there are downsides as well:

  • The loader relies on hierachical directory structures to determine the order of loading files;
    For example, if class B extends class A, then the file containing class A (A.php) needs to be at least one level higher in the directory structure than the file containing class B (B.php).
  • Unresolved classes throw unrecoverable exceptions in PHP. This is very unfortunate, because being able to handle those would mean it would be possible to recover at least those in case the missing class/interface is available to the loader.
  • Some more that elude me right now

The next release will, for the first time, include core files that actually use ZMLoader::resolve('classname'); before the class declaration in order to avoid unloaded classes/interfaces. I o not realy like this at all, but unless I start reorganizing the directory layout (again), there is no way around this.