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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With