Closureクラスは、無名関数(クロージャ)が返すオブジェクトの型なんですが、その他にも便利な機能をもっています。
一番すごいのは、既存クラスを編集せずにメソッドを追加できることかな?
これだけ聞いてもなんのことか分からないと思うけど。
PHP8.1では新しいコールバックの記法にも使われてます。
無名関数の型としてのClosureクラス
Closureクラスの一番の役割は、無名関数のオブジェクトの型として使うことです。
クロージャ、アロー関数も無名関数なので同じClosureクラスオブジェクトを返します。
この型の一番の特長は、なんといっても '()' をオブジェクト変数の後ろに付けて関数を実行できることでしょう。
// 無名関数の戻り値はClosureクラスのオブジェクト
$closure = function ($val1, $val2)
{
return $val1 + $val2;
};
// 無名関数の実行はClosureオブジェクトに '()' を付ける。
$result = $closure(3, 5);
var_dump($result);
int(8)
これが基本的な無名関数の使い方です。
new演算子でインスタンスは作れない
ここからは無名関数の型ではなく、その型がもつ機能について。
Closureクラスのオブジェクトは、無名関数(クロージャ)、アロー関数の戻り値以外は作れません。
new演算子でのインスタンス生成は Error例外が発生します。
どうやら、Closureクラスは無名関数の型以外で使ってほしくないみたい。
Closureクラスのメソッドを使いたければstaticだからいいっしょ? ということらしい。
Closure::bind(), Closure::bindTo(), 既存クラスにメソッドを追加する
Closureクラスのメソッドには、クロージャとクラスオブジェクトをつないで(バインドして)、そのクロージャをクラスのメソッドとして実行できる機能があります。
この機能は、クラスを編集してメソッドを追加する必要がなく、クロージャオブジェクトが有効なかぎり実行できます。
しかし、無名関数なのでクラス内の既存のメソッドからは実行できません。
実行する際の関数名が無いから。
このクロージャ内では、クラス内のprivate, protectedプロパティですら参照、値変更も可能です。
Closure::call(), '()' を付ける無名関数の実行とはちょっとちがう別の実行方法
Closureクラスには、無名関数を実行するメソッドが用意されています。
call()メソッド。
でもこのメソッドは、Closureオブジェクトに '()' を付ける無名関数の実行とは根本的なちがいがあります。
バインドするクラスオブジェクトを必ず指定しなければなりません。
(null指定、バインドのリセットは不可。)
そしてそのバインドはcall()実行時のみが有効です。
Closure::fromCallable(), コールバックを無名関数に変換する
Closureクラスには、コールバックを無名関数へ変換するメソッドがあります。
fromCallable()メソッド。
コールバックは関数名文字列から関数を実行するもので、関数名を定義しない無名関数とは相反するものです。
しかし、PHP8.1から第一級callableが登場し、その中身はClosureオブジェクトです。
最新のコールバックは無名関数を使ってるのでfromCallable()は、その前身とも言える。
知っておいて損はありません。これから主流になるであろう第一級callableへ移行しやすいし。
Closureオブジェクトを作成するところだけ変えれば済むから。
まぁ、既存のコールバック処理からの移行も大したことないけど。
PHP公式ドキュメント