callable の作成
callable は、呼び出し可能な何かを表す型です。
コールバック関数をパラメータとして期待する関数や、
メソッドの引数として渡すことができますし、
直接呼び出すこともできます。
callable 型は、
クラスのプロパティの型宣言には使えません。
代わりに、Closure を型宣言に使ってください。
callable は、複数の異なる方法で作成できます:
-
Closure オブジェクト
-
関数またはメソッドの名前を含む文字列
-
配列。クラス名または object
をインデックス 0 に、メソッド名をインデックス 1 に含みます。
-
__invoke()
マジックメソッドを実装した object
Closure オブジェクトは、
無名関数、
アロー関数、
第一級callableを生成する記法、
もしくは Closure::fromCallable
メソッドを使って作成できます。
注意:
第一級callableを生成する記法
は、PHP 8.1.0 以降でのみ利用可能です。
例1
Closure を使ったコールバックの例
<?php
// Using anonymous function syntax
$double1 = function ($a) {
return $a * 2;
};
// Using first-class callable syntax
function double_function($a) {
return $a * 2;
}
$double2 = double_function(...);
// Using arrow function syntax
$double3 = fn($a) => $a * 2;
// Using Closure::fromCallable
$double4 = Closure::fromCallable('double_function');
// Use the closure as a callback here to
// double the size of each element in our range
$new_numbers = array_map($double1, range(1, 5));
print implode(' ', $new_numbers) . PHP_EOL;
$new_numbers = array_map($double2, range(1, 5));
print implode(' ', $new_numbers) . PHP_EOL;
$new_numbers = array_map($double3, range(1, 5));
print implode(' ', $new_numbers) . PHP_EOL;
$new_numbers = array_map($double4, range(1, 5));
print implode(' ', $new_numbers);
?>
上の例の PHP 8.1 での出力は、このようになります。:
2 4 6 8 10
2 4 6 8 10
2 4 6 8 10
2 4 6 8 10
callable は、
関数名や static メソッドを含む文字列でも表現できます。
ビルトイン関数、またはユーザー定義関数も使えます。
但し、以下のような言語構造は除きます:
array, echo,
empty, eval,
isset,
list, print,
unset
static メソッドは、クラスの object
型をインスタンス化せずに使えます。
クラス名をインデックス 0 に、
メソッド名をインデックス 1 に配置した配列を作成するか、
'ClassName::methodName' のような、
スコープ解決演算子 :: を使った特殊構文が使えます。
インスタンス化された object
のメソッドは、object をインデックス 0 に、
メソッド名をインデックス 1 に配置した配列を作成することで、
callable にできます。
Closure オブジェクトと callable 型の主な違いは、
Closure
オブジェクトがスコープに依存せず常に呼び出せるのに対し、
callable はスコープに依存する場合があり、
直接呼び出せない可能性がある点です。
Closure が、callable を作成する望ましい方法です。
注意:
Closure オブジェクトは、
それが作成されたスコープにバインドされますが、
クラスメソッドを文字列または配列で参照する callable は、
それらが呼び出されたスコープの内部で解決されます。
callable を private または protected メソッドから作成し、
クラスのスコープ外から呼び出せるようにするには、
Closure::fromCallable または、
第一級callableを生成する記法 を使います。
PHP は、コールバック引数として使えるものの、
直接は呼び出せない callable を作成できます。
これらはコンテキスト依存の callable であり、
例えば 'parent::method' や
["static", "method"]
の形で、クラスの継承階層におけるクラスメソッドを参照します。
注意:
PHP 8.2.0 以降では、
コンテキスト依存の callable は推奨されなくなりました。
'parent::method' を
parent::class . '::method'
形式に置き換えることでコンテキスト依存を除去するか、
第一級callableを生成する記法 を使ってください。
例2
call_user_function
を使って、様々なタイプの callable を呼び出す
<?php
// An example callback function
function my_callback_function() {
echo 'hello world!', PHP_EOL;
}
// An example callback method
class MyClass {
static function myCallbackMethod() {
echo 'Hello World!', PHP_EOL;
}
}
// Type 1: Simple callback
call_user_func('my_callback_function');
// Type 2: Static class method call
call_user_func(['MyClass', 'myCallbackMethod']);
// Type 3: Object method call
$obj = new MyClass();
call_user_func([$obj, 'myCallbackMethod']);
// Type 4: Static class method call
call_user_func('MyClass::myCallbackMethod');
// Type 5: Static class method call using ::class keyword
call_user_func([MyClass::class, 'myCallbackMethod']);
// Type 6: Relative static class method call
class A {
public static function who() {
echo 'A', PHP_EOL;
}
}
class B extends A {
public static function who() {
echo 'B', PHP_EOL;
}
}
call_user_func(['B', 'parent::who']); // deprecated as of PHP 8.2.0
// Type 7: Objects implementing __invoke can be used as callables
class C {
public function __invoke($name) {
echo 'Hello ', $name;
}
}
$c = new C();
call_user_func($c, 'PHP!');
?>
hello world!
Hello World!
Hello World!
Hello World!
Hello World!
Deprecated: Callables of the form ["B", "parent::who"] are deprecated in script on line 41
A
Hello PHP!
注意:
call_user_func や call_user_func_array で登録されたコールバックは、
前のコールバックからスローされた例外がキャッチされていない場合はコールされません。