对象在脚本结束前没有被销毁,有人能解释一下为什么使用spl_autoload_register()
可以防止对象在unset()
时被销毁吗?
只要没有对特定对象的其他引用,或者在关闭序列中按任何顺序调用析构函数方法。
spl_autoload_register()
是否引用了注册它的对象,或者发生了什么?
class MyAutoLoader {
public function registerAutoLoader() {
spl_autoload_register(function ($class) {
});
}
public function __destruct() {
echo 'Destroying: ' . get_class($this) . "<br/>";
}
}
$MyAutoLoader = new MyAutoLoader();
$MyAutoLoader->registerAutoLoader();
unset($MyAutoLoader);
echo 'End of script<br/>';
//End of script
//Destroying: MyAutoLoader
spl_autoload_register()是否引用了注册它的对象,或者发生了什么?
是的,它有。但是,并不是因为spl_autoload_register
在类内被调用。这是因为你的Closure
。
请参阅手册:
从PHP 5.4.0开始,当在类的上下文中声明时,当前类会自动绑定到它,使$this在函数的作用域中可用。如果不需要当前类的这种自动绑定,则可以使用静态匿名函数。
当closure
在类中创建时,它将自动绑定伪变量$this
。那么你的实例将有两个引用:
-
$MyAutoLoader
变量; -
Closure
传递给spl_autoload_register
.
我重写了你的例子,有一些不同,你可以看到的行为:
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/>';
,结果将是:
Destroying: MyAutoLoader - Outside the instance
End of script
Destroying: MyAutoLoader - Inside the instance
在最后一个示例中,Closure
是在类作用域之外创建的。所以只有变量$MyAutoLoader2
拥有类的实例。
另一个可能的例子是:
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/>';
在最后一个示例中,我在类的外部创建Closure
,但是我将类作用域绑定到类中,创建对MyAutoLoader
类的新引用。结果将是:
End of script
Destroying: MyAutoLoader
bind
和bindTo
的更多提示,您可以在下面的链接中阅读:
如何调用一个包含了$this闭包的ReflectionFunction ?