クロージャは無名関数のことです。
PHP: 無名関数 – Manual
クロージャは次の様に書け、記述場所に依らない任意のタイミングで実行させることもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class HaveClosure{ private $myClosure ; public function __construct(\Closure $myClosure ) { $this ->myClosure = $myClosure ; } public function run(){ // $this->myClosure()とすると、そんなメソッドはないと怒られます。 $this ->myClosure->__invoke(); } } $instance = new HaveClosure( function (){ echo 'Hello' ;}); $instance ->run(); // Hello |
これを利用すると次の様に処理の途中だけ外部に渡すこともできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class HaveClosure{ private $myClosure ; public function __construct(\Closure $myClosure ) { $this ->myClosure = $myClosure ; } public function run(){ echo 'Hello ' ; $this ->myClosure->__invoke(); echo 'Hi ' ; $this ->myClosure->__invoke(); } } $instance = new HaveClosure( function (){ echo 'Alice' ;}); $instance ->run(); $instance = new HaveClosure( function (){ echo 'Bob' ;}); $instance ->run(); |
例では単純な文字列結合であるため真の利便性が全く分かりません。文字列をプロパティに渡した方がよほどシンプルにまとまります。活躍する場合はSQLのクエリ構築の様な呼び出し側に複雑な処理を委譲させなければならない場合です。複雑すぎるものをパラメータにまとめようとすると多量のクラスか肥大したクラスのどちらかが生まれます。不意に条件分岐が混ざり出すとそれらクラスを総書き換えした方がましな状況にもなります。クロージャはその抽象度と自由度の高さから来るわかりにくさ故、高頻度で使うべきものではないです。しかしながら複雑な状況に用いるとその自由なふるまいがいい感じに複雑さを吸収してくれます。