如果对象注册了spl_autoload_register(),则该对象直到脚本结束才被销毁. [英] Object not being destroyed until end of the script if it registers spl_autoload_register();
问题描述
在脚本结束之前未销毁对象的人可以解释为什么使用spl_autoload_register()
防止unset()
销毁对象的原因.
Object not being destroyed before script ends can someone explain why using spl_autoload_register()
prevents object from destruction when unset()
.
一旦没有其他对特定对象的引用,或者在关闭序列期间以任何顺序进行调用,则析构函数方法将被调用.
The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.
spl_autoload_register()
是否引用了注册该对象的对象,或者会发生什么情况?
Does spl_autoload_register()
have reference to the object that registered it or what happens?
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()是否引用了注册该对象的对象,或者会发生什么情况?
Does spl_autoload_register() have reference to the object that registered it or what happens?
是的,确实如此.但是,这不是因为spl_autoload_register
在类内部被调用.这是因为您的Closure
.
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:
从PHP 5.4.0开始,在类的上下文中声明时,当前类将自动绑定到该类,从而使$ this在函数范围内可用.如果不需要这种自动绑定当前类,则可以使用静态匿名函数代替.
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.
在类中创建closure
后,它将自动绑定伪变量$this
.然后,您的实例将具有两个引用:
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
变量; -
Closure
传递给spl_autoload_register
.
$MyAutoLoader
variable;Closure
passed tospl_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/>';
结果将是:
Destroying: MyAutoLoader - Outside the instance
End of script
Destroying: MyAutoLoader - Inside the instance
在最后一个示例中,Closure
已在类范围之外创建.因此,只有变量$MyAutoLoader2
具有该类的实例.
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.
另一个可能的例子是:
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
类的新引用.结果将是:
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
bind
和bindTo
的其他一些技巧,您可以在下面的链接中阅读:
A few more tips from bind
and bindTo
you can read at the link below:
如何我可以调用ReflectionFunction包装使用$ this的闭包吗?
这篇关于如果对象注册了spl_autoload_register(),则该对象直到脚本结束才被销毁.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!