如果对象注册了spl_autoload_register(),则该对象直到脚本结束才被销毁. [英] Object not being destroyed until end of the script if it registers spl_autoload_register();

查看:91
本文介绍了如果对象注册了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 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/>';

结果将是:

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 

bindbindTo的其他一些技巧,您可以在下面的链接中阅读:

A few more tips from bind and bindTo you can read at the link below:

如何我可以调用ReflectionFunction包装使用$ this的闭包吗?

这篇关于如果对象注册了spl_autoload_register(),则该对象直到脚本结束才被销毁.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆