Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When exactly is the autoloader called?

Tags:

php

autoloader

I have an autoloader that is registered using spl_autoload_register():

class MyAutoLoader{
   public function __construct(){
       spl_autoload_register(array($this, 'loader'));
   }

   public function loader($className){
       var_dump($className);
   }
}

$al = new MyAutoLoader(); //Register the autoloader

From the var_dump(), the autoloader seems to be called on lots of things, things that are data to be inserted into a database, parameterized SQL queries and what not:

string 'name' (length=4)

string 'a:2:{s:5:"label";s:4:"Name";s:8:"required";b:1;}' (length=48)

string 'en_US' (length=5)

string 'object' (length=6)

string 'name = ?' (length=8)

These things will never be classes so should never be loaded using new or class_exists(), etc.

Under what circumstances/function calls are autoloaders called? I would like to put a stop to autoloading "classNames" that are not classes from being called, because each $className is checked using file_exist(), and having these data strings checked is pretty inefficient.


Problem resolved. I first did a back trace as suggested by Brad and dumped the traces to a file (just add a small snippet that opens a file and appends to it).

Obviously, the trace was very big, but I picked the simplest one I could find. Incidentally, that trace happened to be one that called a database (ORM) wrapper I have written to wrap around the awesome RedBean ORM library. The results from me dumping $className also validates that, because those strings are data are going into or coming out of the database.

Having said that, I have a __call() that intercepts methods to my database wrapper, does some processing, pass it to RedBean, process the result, and then sends it back to the caller.

Problem: During the processing, I am making calls to is_subclass_of() and instanceof, which will obviously ask the autoloader to try and load the class (since we don't have any class called name =? loaded, nor does it exist).

The solution was to actually make sure we have an object before calling is_subclass_of() and instanceof: if(is_object($someproperty) && is_subclass_of($someproperty)).

If $someproperty is not an object, the if immediately short-circuits and instanceof and is_subclass_of() is never called, which means the call to the autoloader is never made.

As mentioned by brad, having all sorts of things going to the autoloader to be included using require_once can be a huge security risk and at the same time, hitting the file system so many times using file_exists() is pretty inefficient too.

So, in conclusion, the autoloader is called every time you use instanceof, is_subclass_of, other class-type functions, class-exist functions and reflection methods, as Charles motioned in his answer.

So, the moral of the story is that if you plan to use a class-type function, or any of the functions mentioned above on a variable of mixed type, check it first before passing it to the class-type function.

like image 462
F21 Avatar asked Dec 20 '12 04:12

F21


1 Answers

Under what circumstances/function calls are autoloaders called?

I realize that this has ended up basically being a secondary question given the problems noted in the comments, but it's still worth answering.

Autoload functions, that being a __autoload() function in your code or callbacks registered through spl_autoload_register, are called when -- and only when -- PHP needs to access a class that has not been defined. This is done everywhere with few exceptions, such as class_exists, which have arguments that tell PHP not to call any autoloaders.

The PHP manual has a page dedicated to autoloading. I recommend reviewing it if there's any confusion.

like image 141
Charles Avatar answered Sep 23 '22 00:09

Charles