How can I check if a function already exists in the SPL stack?
-
13-11-2019 - |
Question
I am trying to use spl_autoload_register
and I want to create an if()
statement that will check if the class method as already been registered.
For example:
if (spl_autoload_function(array($this, '_loadClass'))
// Then do nothing
else
// Then run spl_autoload_register(array($this, '_loadClass));
Is something like the above code/method possible?
Solution
I am trying to do an autoloader and I want to create an if statement that will check if the class method as already been registered.
You shouldn't. There is no need to do the if statement; spl_autoload_register
will just ignore a second call with the same arguments:
<?php
$foo = function( $class ) {
return false;
};
spl_autoload_register( $foo );
var_dump( spl_autoload_functions( ) );
spl_autoload_register( $foo );
var_dump( spl_autoload_functions( ) );
The output shows that although we called spl_autoload_register
twice, there is still just one autoloader;
array(1) {
[0]=>
object(Closure)#1 (1) {
["parameter"]=>
array(1) {
["$class"]=>
string(10) "<required>"
}
}
}
array(1) {
[0]=>
object(Closure)#1 (1) {
["parameter"]=>
array(1) {
["$class"]=>
string(10) "<required>"
}
}
}
If you want to make sure a class doesn't register itself twice, you can of course set that in some kind of static member;
<?php
class Foo {
protected static $registered = false;
public function register( ) {
if( self::$registered !== false ) {
return;
}
echo "spl_autoload_register( \$this, '_loadClass' );\n";
self::$registered = true;
}
}
$foo = new Foo( );
$foo->register( );
$bar = new Foo( );
$bar->register( );
The output is obviously one line:
spl_autoload_register( $this, '_loadClass' );
That said, why are you writing your own autoloader? There are numerous out there already, it's hard to believe that none of them fit your requirements.
OTHER TIPS
Disclaimer: I'm not fully confident I understood your question, but I'm confident enough I thought I'd try to answer.
There is no spl_*
function to do this. The closest you get is spl_autoload_functions()
which returns the functions that the spl uses to load, not the functions being loaded.
Solution:
Write your own loader that logs when a function/class has been loaded and register it with spl_autoload_register
.
To answer comment: If you have a class that loads functions, have it append to an internal array of classes it has already loaded.
class Autoloader {
protected $loaded = array();
function autoload($class) {
// find class location
// if it is found:
// include class
$this->loaded[] = $class;
}
function hasLoaded($class) {
return in_array($class, $this->loaded);
}
}
$autoloader = new Autoloader();
spl_autoload_register(array($autloader, 'autoload'));
If you don't care to know if it was loaded by the autoloader, you can simply check for existence using class_exists
.