Lazy Loading in PHP with __autoload

__autoload is one of the magic methods added to PHP in version 5. It creates a very easy way for you to manage all your different class files. Actually, with __autoload you don’t need to manage them.

Often you will see in PHP projects files that include the other files needed for that page. You can then end up with a while bunch of require_once calls and so on. This can be quite tedious to maintain and you may not always need all the files.

When you create a new instance of a class PHP checks for it and if it can’t be found the __autoload method is called. It’s passed in one parameter, the name of the class.

  1. function __autoload($class){
  2.  
  3.     require "/path/to/class/files/$class.php";
  4.  
  5. }
  6.  
  7. $x = new Foo();

Above is a simple example of autoload in action. When a new Foo is created the autoload function requires /path/to/class/files/Foo.php. So with a simple naming convention each class in its own file where the file name is the name of the class (similar to Java) you can easily include files.

This example can be taken slightly further to manage hierarchies of classes…

  1. function __autoload($class){
  2.  
  3.     $class = str_replace(‘_’, ‘/’, $class);
  4.     $path = "/path/to/class/files/$class.php";
  5.     require $path;
  6.  
  7. }
  8.  
  9. $x = new Foo_Bar();

The above code simply replaces all underscores ( _ ) with forward slashes ( / ) before requiring the class. The naming convention changes slightly for this, the class name Foo_Bar would be found in following path: /path/to/class/files/Foo/Bar.php.

  1. function __autoload($class){
  2.  
  3.     $class = str_replace(‘_’, ‘/’, $class);
  4.     $path = "/path/to/class/files/$class.php";
  5.  
  6.     if(file_exists($path)){
  7.         require $path;
  8.     } else {
  9.         // Error handling here, log it etc.
  10.         // Exceptions cannot be thrown.
  11.     }
  12.  
  13. }
  14.  
  15. $x = new Foo_Bar_Fail();

The final example shows the same code again with some optional error checking. It allows you to log errors and so on. However, exceptions cannot be thrown by __autoload unless its being called by class_exists. Since this function calls autoload to look for classes. When trying to throw exceptions, PHP runs into a fatal error before its thrown due to the order or __autload. This means a fatal error will be triggered as the class can’t be found and the exception will vanish.

Following up to this post I plan to do one of spl_autoload soon. With this you can have PHP automatically run its own autoload procedure on include paths. For further reading on this follow the link below. The documentation is a little sparse however.

Enjoy, lazy loading!

Useful links;

Tags: , ,

13 Responses to “Lazy Loading in PHP with __autoload”

  1. Thomas Says:

    Thanks, this really helped. Didn’t know there was anything like autoload <3

  2. Dougal Says:

    No problem, glad to see my new blog is helping some people.

  3. Jrgns Says:

    Do you have the code in production somewhere? As far as I know Exceptions doesn’t work inside of __autoload…

  4. Dougal Says:

    Your completely right. I’m sure I had a test case of this working but I must have been tripping out.

    Updating it now to reflect that, thanks.

  5. Jrgns Says:

    It’s a pity, tough. I rely heavily on autoloading of classes, many times with actually knowing if it can/may happen. Exceptions would have made it much more robust!

  6. Dougal Says:

    Yeah, I completely agree.

    There are some work arounds to use class_exists with it, you can see them in the comments in the PHP docs. They are very messy however - but sometimes PHP tends to be like that.

  7. CHia Says:

    Can the __autoload declare in the class function ?

  8. Dougal Says:

    No, __autoload must be declared in the global namespace. This is because it needs to be accessible from everywhere.

    This makes it different from the other ‘magic methods’ as its not defined in a class or specific to a particular object instance.

    As far as I know, in PHP 5.3 you can have one __autoload function per namespace. I’m not sure about this yet…

  9. Ovidiu Curcan Says:

    spl_autoload_register() should be preferred. It allows multiple handlers to be registered.

  10. Lee Says:

    __autoload can only be used once.

    A better solution is http://php.net/spl_autoload_register as it allows you to register as many autoload functions/methods as necessary.

  11. Dougal Says:

    Ovidiu Curcan, thats like saying Arrays are better because they can hold more than one value. It depends on the situation. It made sense to cover this first, I was going to cover spl_autoload but I havn’t had the time yet.

  12. Ovidiu Curcan Says:

    @Dougal: Ok, I’ll play along. You say it depends on the situation. Could you describe a situation where __autoload() is better than spl_autoload_register()? I agree that it makes sense covering this first (people should be informed after all), but there should be a warning at the top: “do not use, there’s something better”. :)

  13. Dougal Says:

    It’s more a case of if it’s not needed why use it? I’ve got many projects that use __autoload, I’ve only used spl_autoload_register a few times. I haven’t come across the need for more than one very often.

    I personally think it’s better to try and stick to one. As the magic methods functionality is invisible once implemented, if you use too much it can lead to very hard to debug problems.
    Unless you are combining a number of projects together with different structures in the class files then I don’t think you need spl_autoload. I actually can’t think of a good example for needing it besides what I just mentioned.

    Damn, I need to make this textarea bigger… *goes away for a minute* … that’s better!

Leave a Reply