[PHP] コールバック関数について
PHPのコールバック関数とは、呼び出し先関数の中でさらに呼び出される関数のことを言います。コールバック=「後で呼び出される」という意味があります。
ここではコールバック関数の基本的な使い方、無名関数を使った呼び出し、コールバック関数を使ったいくつかの例についてまとめていきます。
コールバック関数
実装例
コールバック関数はcallable型で定義され、呼び出された関数内で実行(コールバック)されます。
以下の例は一番簡単な例です。test_callback関数の引数にコールバックさせたい関数名を指定して、test_callback内でコールバックしています。
コード
function test_function() {
print __FUNCTION__ . "\n";
}
function test_callback(callable $function) {
$function();
}
test_callback("test_function");
実行結果
$ php test_callback.php test_function
無名関数で指定する実装例
callable型は以下のように無名関数で指定することも可能です。
コード
function test_callback(callable $function) {
$function();
}
test_callback(function() {
print __FUNCTION__ . "\n";
});
実行結果
無名関数で指定した場合、関数名が無いので __FUNCTION__ は以下のように出力されます。
$ php test_callback.php {closure}
array_map関数
配列の全要素に対して処理を行う
array_map関数は配列の全要素に対して処理を行うための関数です。従来配列の全要素に対して処理を行う場合、for文やforeach文を使用して記述していましたが、これが簡潔に記述できるようになります。
なお、array_map関数は引数に指定した配列を直接変更するのではなく、処理した結果の配列を返します。
コード
以下のコードでは、配列 $array には連想配列のリストを保持しており、array_map関数でこの連想配列のname属性を大文字に変換したものを保存しています。
$array = [
["key" => 1, "name" => "Apple"],
["key" => 2, "name" => "Lemon"],
["key" => 3, "name" => "Strawberry"],
];
print_r($array);
$array_upper = array_map(function($value) {
$value['name'] = strtoupper($value['name']);
return $value;
}, $array);
print_r($array_upper);
実行結果
$ php test_callback.php Array ( [0] => Array ( [key] => 1 [name] => Apple ) [1] => Array ( [key] => 2 [name] => Lemon ) [2] => Array ( [key] => 3 [name] => Strawberry ) ) Array ( [0] => Array ( [key] => 1 [name] => APPLE ) [1] => Array ( [key] => 2 [name] => LEMON ) [2] => Array ( [key] => 3 [name] => STRAWBERRY ) )
配列の全要素に対して、もう一方の配列を使って処理を行う
array_map関数は第三引数以降にさらに配列を受け取ることが出来ます。第三引数以降に渡された配列は、callable型のfunctionの引数で受け取ることが出来ます。
つまり複数の配列に対して順に、対応した要素をもって処理することが出来ます。
コード
以下のコードでは、配列$array に対して 配列$prices から対応した値を1.1倍して、price要素として追加しています。
$array = [
["key" => 1, "name" => "Apple"],
["key" => 2, "name" => "Lemon"],
["key" => 3, "name" => "Strawberry"],
];
$prices = [100, 150, 200];
print_r($array);
$array_upper = array_map(function($value, $price) {
$value['price'] = (int) ($price * 1.10);
return $value;
}, $array, $prices);
print_r($array_upper);
実行結果
$ php test_callback.php Array ( [0] => Array ( [key] => 1 [name] => Apple ) [1] => Array ( [key] => 2 [name] => Lemon ) [2] => Array ( [key] => 3 [name] => Strawberry ) ) Array ( [0] => Array ( [key] => 1 [name] => Apple [price] => 110 ) [1] => Array ( [key] => 2 [name] => Lemon [price] => 165 ) [2] => Array ( [key] => 3 [name] => Strawberry [price] => 220 ) )
usort関数
オブジェクトに対して特定のルールで並べ替えを行う
usort関数を使うと、オブジェクトに対して特定のルールで並べ替えを行います。
第一引数で並べ替えの比較のためのルールをcallable型の引数で指定し、第二引数で並べ替える配列を指定します。
なお、usort関数は第二引数で指定された配列を直接変更します。
コード
以下の例ではPerson型のオブジェクトに対して、age属性の昇順で並べ替えを行っています。
なお、比較演算子の <=> は、宇宙船演算子と言って、左辺が小さければ-1、左辺が大きければ1、同じであれば0を返します。
class Person {
private int $id;
private string $name;
private int $age;
public function __construct(int $id, string $name, int $age) {
$this->id = $id;
$this->name = $name;
$this->age = $age;
}
public function getId() : int {
return $this->id;
}
public function getName() : string {
return $this->name;
}
public function getAge() : int {
return $this->age;
}
}
$persons = [
new Person(1, 'Test Name 1', 30),
new Person(2, 'Test Name 2', 20),
new Person(3, 'Test Name 3', 25),
];
usort($persons, function(Person $p1, Person $p2) {
return $p1->getAge() <=> $p2->getAge();
});
print_r($persons);
実行結果
実行結果を確認すると、age属性の昇順でソートされていることが確認できます。
$ php test_callback.php Array ( [0] => Person Object ( [id:Person:private] => 2 [name:Person:private] => Test Name 2 [age:Person:private] => 20 ) [1] => Person Object ( [id:Person:private] => 3 [name:Person:private] => Test Name 3 [age:Person:private] => 25 ) [2] => Person Object ( [id:Person:private] => 1 [name:Person:private] => Test Name 1 [age:Person:private] => 30 ) )
アロー関数
上記コードのusort関数の呼び出しは、アロー関数によって以下のように置き換えることが可能です。
usort($persons, fn(Person $p1, Person $p2) => $p1->getAge() <=> $p2->getAge());
実行結果は同じです。
コメント
コメントを投稿