はじめに
PHPで関数を変数に代入したり、関数の引数として渡すコードを見かけることがあります。
これは「ラムダ関数」「無名関数」「匿名関数」などと呼ばれますが、その正体は何なのか。
この記事では、PHPにおけるラムダ関数の本質について、自分の理解をまとめます。
無名関数の定義と使い方
まず、PHPでの無名関数(匿名関数)の定義は以下のように書けます。
$lambda = function (string $name): string {
return "hello, " . $name;
};
echo $lambda("taro"); // hello, taro
この $lambda
は、実行可能な「関数のようなもの」ですが、実はその正体は Closure
というクラスのインスタンスです。
var_dump($lambda);
// object(Closure)#1 (0) { }
実は「関数のように振る舞うオブジェクト」
PHPのラムダ関数は、実体としては Closure
クラスのオブジェクトです。
Closure
は特殊な __invoke()
メソッドを持っており、オブジェクトでありながら ()
を使って呼び出すことができます。
これは PHP の「呼び出し可能オブジェクト(invokable object)」という仕組みによって実現されています。
class Doubler {
public function __invoke($x) {
return $x * 2;
}
}
$d = new Doubler();
echo $d(10); // 20
この仕組みと同じように、ラムダ関数も $lambda()
のように書くことで __invoke()
が呼び出されています。
関数のようでいて、状態も持てる
オブジェクトであるということは、状態(値)を保持することも可能です。
PHPでは use
を使うことで、外部の変数をクロージャに取り込むことができます。
$count = 0;
$increment = function () use (&$count) {
$count++;
};
$increment();
echo $count; // 1
このように、ラムダ関数は「関数のように使える」だけでなく、「状態を持つ」こともできるという点で、関数とオブジェクトの中間のような存在です。
まとめ
PHPにおけるラムダ関数(無名関数 / 匿名関数)とは:
-
Closure
クラスのオブジェクトである -
__invoke()
により関数のように呼び出せる - 他の関数の引数として渡すことができる(高階関数)
-
use
を使えば状態を持たせることができる
つまり、PHPのラムダ関数は「呼び出し可能なオブジェクト」であり、関数とオブジェクトの性質をあわせ持つ存在です。
おわりに
最初は「function(){} が変数に入るなんて不思議だ」と感じていましたが、内部的にはオブジェクトとして扱われていると知ることで、理解が深まります。