Page 1 of 1

Correct use of __autoload()

Posted: Tue May 11, 2010 3:40 am
by social_experiment
This is a question about __autoload() and the correct use of the function. If i had the following two pages, each containing a class and i wished to use '__autoload()' would the following code examples be the correct :

One.php

Code: Select all

 //first page with a class
 <?php class One {
  public function hello_world() {
   echo 'Hello World';
  }
 } ?>

Two.php

Code: Select all

 //second page with a class
 <?php class Two {
  public function hello_name() {
   echo 'Hello Bob';
  }
 } ?>

On the page where i am implementing the classes my code would be :

Implementation page

Code: Select all

 //Implementation excerpt
 <?php function __autoload($class) {
  $file = "$class.php";
  include_once "path_to_file/$file";
 }
 
 //Instantiate objects 
 $Obj1 = new One();
 $Obj2 = new Two();
 ?> 

If i had 5 pages that required both or at least one of the classes, would each of those 5 pages contain the code from the implementation excerpt?

Re: Correct use of __autoload()

Posted: Tue May 11, 2010 3:53 am
by Weirdan
social_experiment wrote:If i had 5 pages that required both or at least one of the classes, would each of those 5 pages contain the code from the implementation excerpt?
More or less yes. I'd advise to move __autoload() definition to separate file and include it though (also rename it to something else and register with spl_autoload_register).

Re: Correct use of __autoload()

Posted: Tue May 11, 2010 6:53 am
by social_experiment
Thanks for the advice, I've put my __autoload() function in a seperate file, included the file, and it works a treat. I've attempted using spl_autoload_register() without success.

I also visited http://php.net/manual/en/function.spl-a ... gister.php but the examples there (posted by users) are slightly above my understanding.

Apart from what seems to be a smoother way (using spl_autoload_register()) are there any negative aspects when using __autoload()?

Re: Correct use of __autoload()

Posted: Tue May 11, 2010 11:34 am
by thinsoldier
social_experiment wrote:Apart from what seems to be a smoother way (using spl_autoload_register()) are there any negative aspects when using __autoload()?
As long as you keep your class files named consistently and arranged in sensible folders so the autoloader doesn't have to do a bunch of random searching all over the file system it should be fine.

In my messy code there are cases where autoload has to search a dozen paths before it finds the right class file. On my test server this has no negative effects but on my severely overburdened production server it can be almost half a second to find the right file via autoload. So unfortunately I wind up always manually including the full path to the files I need specifically.

Re: Correct use of __autoload()

Posted: Tue May 11, 2010 1:18 pm
by requinix
Using __autoload only allows for one autoloading function. In my experience that's been enough (as it only really has one purpose) - the issue is having multiple paths to search. You can deal with that by coding a more intelligent __autoload that looks at the include_path, which you then modify to include whatever paths to search.

But SPL's autoloader is a more flexible approach. It's quite possible that in the future you'll need a way to (a) include regular classes without any additional work, and (b) include some types of classes and then immediately "register" them somewhere (like with a plugin system). With just __autoload it would be complicated to do that, but with SPL's autoload you can have multiple autoloaders performing different actions.

To be more specific, I create one autoload function and register it with sql_autoload_register. Brief example:

Code: Select all

function autoload($classname) {
    $path = str_replace("_", DIRECTORY_SEPARATOR, $classname) . ".php";
    foreach (explode(PATH_SEPARATOR, get_include_path()) as $search) {
        $file = $search . "/" . $path;
        if (is_file($file)) {
            require_once $file;
            return $file; // if autoload() is called manually, returns the filename for the class
        }
    }
}
spl_autoload_register("autoload");

Re: Correct use of __autoload()

Posted: Tue May 11, 2010 4:47 pm
by social_experiment
thinsoldier wrote:As long as you keep your class files named consistently and arranged in sensible folders so the autoloader doesn't have to do a bunch of random searching all over the file system it should be fine.
That's how i normally keep things but i recently started to focus my coding style to a more object-orientated style so i will have multiple class files and i will most likely end up with a lot of 'include_once' statements(my aim is to avoid this). Thanks for the input and advice :)
tasairis wrote:To be more specific, I create one autoload function and register it with sql_autoload_register
The example you gave, how would i implement it (or something similar to it)? Im assuming i have to call it somewhere on the page that requires my class pages to use it, is this assumption correct? My previous attempts ended up with a exception being thrown at me.

Re: Correct use of __autoload()

Posted: Tue May 11, 2010 6:08 pm
by Christopher
tasairis wrote:To be more specific, I create one autoload function and register it with sql_autoload_register. Brief example:

Code: Select all

function autoload($classname) {
    $path = str_replace("_", DIRECTORY_SEPARATOR, $classname) . ".php";
    foreach (explode(PATH_SEPARATOR, get_include_path()) as $search) {
        $file = $search . "/" . $path;
        if (is_file($file)) {
            require_once $file;
            return $file; // if autoload() is called manually, returns the filename for the class
        }
    }
}
spl_autoload_register("autoload");
I am a little confused why you would manually search the include path, when that is exactly what require_once($path) would do? I would think that internally it would be done in a faster/optimized fashion. I must be missing something obvious.

Re: Correct use of __autoload()

Posted: Tue May 11, 2010 6:47 pm
by Weirdan
Christopher wrote:I am a little confused why you would manually search the include path, when that is exactly what require_once($path) would do?
This code has a little subtle difference as opposed to straight require_once - it won't fail if file is not found in include_path. Basically, it's reimplementation of include_once(), but without nasty warnings when file is not found.

Also it could allow to cache class -> filename mappings, including misses (this is not done here though) to avoid repeated lstat()s. This can save you a lot of IO if some of the classes are loaded via second autoloader in chain.