PHP5.4から実装されたClosure::bind()
を用いる。
たとえば下記のようなコード。
1 2 3 4 5 6 7 8 9 10 11 12 |
class hello { private function world() { echo 'hello World'; } } $class = new hello(); $class->world(); |
当然Fatal error: Call to private method hello::world() from context
と怒られる。
しかしClosure::bind()
を次のように用いると。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class hello { private function world() { echo 'hello World'; } } Closure::bind(function() { $class = new hello(); $class->world(); }, null, 'hello')->__invoke(); |
なんと画面にhello World
が表示される。
第1引数に渡した関数内の処理は、第3引数に渡した名前のクラス内で実行されているものとして扱われるため、正常に関数を呼び出すことができている。
そう、Closure::bind()
は無名関数に限り実行時コンテキストを動的に変更できるというチート機能を有しているのである。
これを応用すると、PHPUnitでのテストケースにおいてもprivateな関数をテストすることができるようになるため、非常に強力な機能の一つであると言える。