Force autoloading of a specific class

1.4k views Asked by At

This previous question shows how to force autoloading of all classes.

However I need to force autoloading of just one class on its own. How could I do that?

It mustn't:

  • Involve changing the class's source code
  • Rely on any part of the class's source code (methods, variables, modifiers e.g. it must be free to change from concrete to abstract without affecting this).

Also, preferably it would not involve coding the class's name as a string. (To help with IDE refactoring and so on).

The best option I have found so far would be to just use spl_autoload_call():

spl_autoload_call("Jodes\\MyClass");

or for non-namespaced classes:

spl_autoload_call("MyClass");
2

There are 2 answers

0
theking2 On

I had exactly the same problem and tried different autoload functions. On a Windows PHP 8.1.5 version I had these two different autoloaders:

set_include_path(get_include_path() . PATH_SEPARATOR . 'class/');
spl_autoload_extensions('.class.php');
spl_autoload_register();

or

$autoloader = function( string $class_name )
{
  $filename = $_SERVER["DOCUMENT_ROOT"].'/class/' . str_replace( '\\', '/', $class_name)    . '.class.php';
  require_once $filename;
};

// our class loader
spl_autoload_register( $autoloader );

which seemingly do the same thing.

As one class file in my application also create some supporting global function variables that can be used during construction of the said class I needed to force the class file loading before accessing said functions variables and construction. I did this with the class_exist() on the specific class.

Using the spl_auoload_extenions version this worked fine; using the spl_autoload_register($autoloader) version causes an undefined variable when using the function variables.

1
Victor Schröder On

I had the same need recently. Doing require_once was not an option because the class really needed to be located by the autoloader because of some more complex rules, there was no way to know exactly the path to the file with the class.

Although the function spl_autoload_call($classname) is designed to do precisely this, it suffers from a fundamental flaw: it will throw a FATAL ERROR in case you call it twice for the same classname or even if some of the child classes of that class were already loaded. This happens because it's not possible to redeclare classes in PHP:

<?php

spl_autoload_call('TheClass');
// no problem

spl_autoload_call('TheClass');
// PHP Fatal error:  Cannot declare class TheClass, because the name is already in use in ... on line ...

My solution for this problem is no rely on the side-effect of class_exists($classname) which was not designed for this purpose, but is more configurable and, therefor, offers more control about triggering the autoloader.

Even better, it has absolutely no problem on multiple calls or if something was already loaded in the inheritance chain. It simply has the side-effect (if you want) of requiring the file, if the class is not there yet!

<?php

class_exists('TheClass');
// no problem

class_exists('TheClass');
// already exists. No need to autoload it and no fatal errors!

With this you have a safe and idempotent way to load the class through the autoloader.

And, if you don't want to hard-code the string with the classname in there, from PHP version 5.5 onward, you can use the ::class pseudo constant, which is resolved at compile time to the string with the fully qualified classname (including namespaces):

<?php

class_exists(TheClass::class);