2011-12-05 2 views
80

PHPマニュアル状態は5.4.0

5.4.0

PHPの前に無名関数から$thisを使用することはできませんが事前にanonymous functions pageにあります。しかし、変数に$thisを代入し、その変数を関数定義のuseステートメントに渡すことで、動作させることができます。

$CI = $this; 
$callback = function() use ($CI) { 
    $CI->public_method(); 
}; 

これは良い方法ですか?
PHP 5.3を使用して匿名機能の中で$thisにアクセスするより良い方法はありますか?

+1

だけマイナーフォーラムコンベンション - お好みの答えを反映するために質問を編集するよりも、答えを受け入れるために、通常は良いです。主にこれは、応答が永続的にも意味をなさないようにするだけでなく、正解のためのクレジットを与えることです。 – halfer

+3

'$ CI = $ this;'と '$ CI =&$ this;' **は実際には同一ではないことに注意してください。多分あなたの目的のために、しかし彼らは同じではありません。 '$ CI = 'bla'を試してください。 var_dump($ this); 'の両方のバージョンを使用して違いを確認してください。 – Rudie

+1

@Rudieあなたのコメントのために[documentation](http://php.net/manual/en/language.oop5.references.php)を追加しています – steampowered

答えて

61

外部からの呼び出しとしてカウントするため、保護されたメソッドまたはプライベートメソッドを呼び出そうとすると失敗します。そこ私の知る限りでは5.3でこの問題を回避する方法はありませんが、PHP 5.4に来る予想通り、それは箱から出して、動作します:

さらに
class Hello { 

    private $message = "Hello world\n"; 

    public function createClosure() { 
     return function() { 
      echo $this->message; 
     }; 
    } 

} 
$hello = new Hello(); 
$helloPrinter = $hello->createClosure(); 
$helloPrinter(); // outputs "Hello world" 

、あなたは何$を変更することができます

効果的
class Hello { 

    private $message = "Hello world\n"; 

    public function createClosure() { 
     return function() { 
      echo $this->message; 
     }; 
    } 

} 

class Bye { 

    private $message = "Bye world\n"; 

} 

$hello = new Hello(); 
$helloPrinter = $hello->createClosure(); 

$bye = new Bye(); 
$byePrinter = $helloPrinter->bindTo($bye, $bye); 
$byePrinter(); // outputs "Bye world" 

、anonymus機能は、最初のパラメータは、このポイントを$かを指定するために使用することができbindTo() method、2番目のパラメータのコントロールがあります:これはanonymus機能(閉鎖再バインド)のために、実行時を指し可視性レベルはとなるはずです。 2番目のパラメータを省略すると、可視性は "外側"からの呼び出しのようになります。パブリックプロパティのみにアクセスできます。また、bindToが動作する方法を書き留めて、元の関数を変更しないでください。新しいものを返します

+1

答えを正しくマークしますが、他の読者を明確にするために:規約'$ this'を参照しているオブジェクトを使ったパブリックメソッドのために働くでしょう。 – steampowered

+5

[非公開のメソッド](http://stackoverflow.com/a/6386863/90527)は、リフレクションを使用してアクセスできます。非効率で少し悪いですが、うまくいきます。 – outis

1

参考にして渡すのが正しい方法だと思われます。 PHP 5を使用している場合は$thisの前に&シンボルが必要ではありません。

+2

4.xは匿名関数をサポートしていないので、OPは5.3以上を使用しなければなりません: – halfer

1

これは問題ありません。

$CI = $this; 

...オブジェクトを含む割り当ては、オブジェクト全体ではなく参照を常にコピーするためです。

5

これは正常な方法です。
b.t.w、オブジェクトがrefを何らかの方法で渡すので、これがなくても動作する&を削除しようとします。

5

オブジェクトを参照渡しにPHPに依存するとは限りません。参照自体を割り当てるとき、元のポインタが変更されたほとんどのOO言語と同じ動作ではありません。

あなたの例:

$CI = $this; 
$callback = function() use ($CI) { 
$CI->public_method(); 
}; 

は次のようになります。その上で、最終的な呼び出しはあなたが持つかもしれない再び他、行われた後REFERENCE "&" と$ CIを割り当てる必要があります

$CI = $this; 
$callback = function() use (&$CI) { 
$CI->public_method(); 
}; 

NOTE PHPが参照にアクセスする際の予測不可能な出力は、元のクラスにアクセスすることと必ずしも同じではありません。

http://php.net/manual/en/language.references.pass.php