Does spl_autoload_register() have reference to the object that registered it or what happens?
Yes, it does. But, doesn't because spl_autoload_register
was called inside the class. That's happening because of your Closure
.
As you can read in manual:
As of PHP 5.4.0, when declared in the context of a class, the current class is automatically bound to it, making $this available inside of the function's scope. If this automatic binding of the current class is not wanted, then static anonymous functions may be used instead.
When the closure
has been created inside the class, it'll bound automatically the pseudo-variable $this
. Then your instance will have two references:
-
$MyAutoLoader
variable;
-
Closure
passed to spl_autoload_register
.
I've rewritten your example with a few differences which you can see the behavior:
class MyAutoLoader {
private $instance = "Outside";
public function registerAutoLoader(Closure $closure = null) {
//If a closure ins't passed as parameter, a new one will be created
if (!$closure instanceof Closure)
{
$this->instance = "Inside";
//A closure created inside a class will bound the pseudo-variable $this
$closure = function ($class) {};
}
spl_autoload_register($closure);
}
public function __destruct() {
printf('Destroying: %s - %s instance<br/>' , get_class($this) , $this->instance);
}
}
$MyAutoLoader = new MyAutoLoader();
$MyAutoLoader->registerAutoLoader();
$MyAutoLoader2 = new MyAutoLoader();
//A closure created outside of a class doesn't have the class scope
$MyAutoLoader2->registerAutoLoader(function($class){});
unset($MyAutoLoader , $MyAutoLoader2);
echo 'End of script<br/>';
And the result will be:
Destroying: MyAutoLoader - Outside the instance
End of script
Destroying: MyAutoLoader - Inside the instance
In the last example, the Closure
has been created out of the class scope. So only the variable $MyAutoLoader2
has the instance of the class.
Another possible example can be:
class MyAutoLoader {
public function registerAutoLoader(Closure $closure) {
//Binding the class scope to the closure
$closure = $closure->bindTo($this);
spl_autoload_register($closure);
}
public function __destruct() {
printf('Destroying: %s <br/>' , get_class($this));
}
}
$MyAutoLoader = new MyAutoLoader();
$MyAutoLoader->registerAutoLoader(function($class){});
unset($MyAutoLoader);
echo 'End of script<br/>';
In this last example, I'm creating the Closure
outside of class, but I'm binding the class scope into the class, creating a new reference to MyAutoLoader
class. The result will be:
End of script
Destroying: MyAutoLoader
A few more tips from bind
and bindTo
you can read at the link below:
How can I invoke a ReflectionFunction wrapping a closure that utilizes $this?