Sunday, March 7, 2010

Implied Class Pattern with __autoload()

One more thing about not-so-obvious capabilities of PHP: Implied Class Pattern.

Let's say you are implementing a Model layer in your MVC where each model class corresponds to one table. So if your table name is "member" than you might want to have class MemberModel. Then you create table "city", then "state", then forty more tables. So you end up with forty more classes that share exactly the same functionality with one only difference: table name.

Here is how every one of your files might look like:

<?php
    class MemberModel extends Model {}
?>

Of course you will try to use __autoload() to dynamically load them at run time.
But loading extra forty (or more) files translates into reading from the disk just as many times. Not the most efficient solution.

Another inefficient thing about this approach is having to write those files every time you add a table to your database.

All of this can be avoided with Implied Class Pattern. Consider the following code:

function __autoload($sClassName) {
    $bLoaded = false;
    foreach ($_ENV['AUTOLOAD_PATHS'] as $sAutoloadPath) {
        $sFilePath = $sAutoloadPath.$sClassName.'.php';
        if (file_exists($sFilePath)) {
            require_once $sFilePath;
            $bLoaded = true;
            break;
        }
    }
    if (!$bLoaded) {
        // Implied classes
        if (preg_match('/Model$/', $sClassName)) {
            eval("class $sClassName extends Model {}");
        } else {
            throw new Exception('Class '.$sClassName.' not found');
        }
    }
}

This way whenever you need a specific subclass of Model it is created for you "on-the-fly" avoiding multiple redundant files and disk activity.

Of course if you need to add a model-specific functionality, you can always add that extra file into your autoloaded directory and it will load the implemented class before it tries to imply it. So win-win.

To summarize: Where do you use Implied Class Pattern? Whenever you have multiple subclasses of one base class with little or no difference from one another.

Enjoy.

1 comment:

Petah said...

Have you looked as PSR0 auto loading? Also PHP will cache disk access and will only read the file once, it will however stat the file. But this is very fast.