2016-10-31 2 views
1

スクリプトが終了する前にオブジェクトが破壊されていない理由を説明できる理由spl_autoload_register()は、unset()でオブジェクトが破壊されるのを防ぎます。オブジェクトはspl_autoload_register();を登録するとスクリプトの終わりまで破壊されません。

デストラクターメソッドは、特定のオブジェクトへの他の参照がないとすぐに、またはシャットダウンシーケンス中に任意の順序で呼び出されます。

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 

答えて

0

(spl_autoload_registerをい)、それを登録したり、何が起こるかのオブジェクトへの参照を持っていますか?

はい、彼はそうですが、spl_autoload_registerがクラス内で呼び出されたためです。これはあなたのClosureが原因で発生しています。

手動でreadができるように:クラスのコンテキスト内に宣言する場合、現在のクラスが自動的に内部$これを利用可能にすること、それにバインドされたPHP 5.4.0、のよう

を関数のスコープ。現在のクラスのこの自動バインディングが望ましくない場合は、代わりに静的な無名関数を使用できます。

クラス内でクロージャを作成すると、擬似変数$thisが自動的にバインドされます。インスタンスには2つの参照があります:

  • 可変;
  • Closurespl_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 create outside of a class won't have the class scope 
$MyAutoLoader2->registerAutoLoader(function($class){}); 

unset($MyAutoLoader , $MyAutoLoader2); 

echo 'End of script<br/>'; 

そして、その結果は次のようになります。

Destroying: MyAutoLoader - Outside instance 
End of script 
Destroying: MyAutoLoader - Inside instance 

最後の例では、Closureクラススコープから作成されました。したがって、変数$MyAutoLoader2だけが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への新しい参照を作成し、クラスにクラススコープを結合していますクラス。結果は以下のようになります。

End of script 
Destroying: MyAutoLoader 

bindからいくつかのより多くのヒントやbindToあなたは下のリンクで読むことができます:

How can I invoke a ReflectionFunction wrapping a closure that utilizes $this?

関連する問題