7

I have read about dynamically loading your class files when needed in a function like this:

function __autoload($className)
{
   include("classes/$className.class.php");
}

$obj = new DB();

Which will automatically load DB.class.php when you make a new instance of that class, but I also read in a few articles that it is bad to use this as it's a global function and any libraries that you bring into your project that have an __autoload() function will mess it up.

So does anyone know of a solution? Perhaps another way to achieve the same effect as __autoload()? Until I find a suitable solution I'll just carry on using __autoload() as it doesn't start becoming a problem until you bring in libraries and such.

Thanks.

Josh
  • 277
  • 2
  • 4
  • 7

6 Answers6

11

I have used the following code to use spl_autoload_register in a way that it will degrade if it isn't present, and also handle libraries that use __autoload, that you need to include.

//check to see if there is an existing __autoload function from another library
if(!function_exists('__autoload')) {
    if(function_exists('spl_autoload_register')) {
        //we have SPL, so register the autoload function
        spl_autoload_register('my_autoload_function');      
    } else {
        //if there isn't, we don't need to worry about using the stack,
        //we can just register our own autoloader
        function __autoload($class_name) {
            my_autoload_function($class_name);
        }
    }

} else {
    //ok, so there is an existing __autoload function, we need to use a stack
    //if SPL is installed, we can use spl_autoload_register,
    //if there isn't, then we can't do anything about it, and
    //will have to die
    if(function_exists('spl_autoload_register')) {
        //we have SPL, so register both the
        //original __autoload from the external app,
        //because the original will get overwritten by the stack,
        //plus our own
        spl_autoload_register('__autoload');
        spl_autoload_register('my_autoload_function');      
    } else {
        exit;
    }

}

So, that code will check for an existing __autoload function, and add it to the stack as well as your own (because spl_autoload_register will disable the normal __autoload behaviour).

Alistair Evans
  • 36,057
  • 7
  • 42
  • 54
  • A Good solution, though I would make the minor alteration of just using spl_autoload anyway, irrelevant of the existing autoload, just spl load the __autoload function if it exists, then spl load your function. – Aatch Feb 01 '11 at 04:22
  • Yeah, you can do that, although if i understand you correctly, you're just effectively swapping if statements around really with that though. – Alistair Evans Feb 01 '11 at 09:40
7

You can use spl_autoload_register(), adding any existing __autoload() magic to the stack.

function my_autoload( $class ) {    
    include( $class . '.al.php' );
}
spl_autoload_register('my_autoload');

if( function_exists('__autoload') ) {
    spl_autoload_register('__autoload');
}                                                                                         

$f = new Foo;
Annika Backstrom
  • 13,937
  • 6
  • 46
  • 52
4

The correct way would be to use spl_autoload_register. To save a __autoload function that some 3rd-party introduced you can put that function on the autoloader-stack as well:

if (function_exists('__autoload')) {
    spl_autoload_register('__autoload');
}
Stefan Gehrig
  • 82,642
  • 24
  • 155
  • 189
3

Use spl_autoload_register instead of __autoload. This will allow you to add your autoload function into the stack.

Ololo
  • 1,087
  • 9
  • 16
  • I think `spl_autoload_register` clobbers any existing `__autoload` function, so if a library uses it, you're wiping out the library's function. Having said that, if two libraries both define an `__autoload` function you're a bit screwed anyway! – Andy Shellam Apr 13 '10 at 14:59
  • If your code has an existing __autoload function then this function must be explicitly registered on the __autoload stack. This is because spl_autoload_register() will effectively replace the engine cache for the __autoload function by either spl_autoload() or spl_autoload_call(). This is taken from the manual page – Ololo Apr 13 '10 at 15:03
0

You could use Zend_Loader. (Assuming Zend Framework is available for you...)

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
0

Best you can do is to define your own object responsible for autoloading for any subsystem you are programming.

For example:

class BasketAutoloader
{
  static public function register()
  {
    spl_autoload_register(array(new self, 'autoload'));
  }

  public function autoload($class)
  {
    require dirname(__FILE__).'/'.$class.'.php';
  }
}
smentek
  • 2,820
  • 1
  • 28
  • 32