アロー関数は短い無名関数です:fn($x) => $x * 2。=>のあとの本体は1つの式で、その値が返され、式が使う周りのコードの変数は自動的に値でキャプチャされます。アロー関数はPHP 7.4から使え、おもにコールバックとして使われます。
構文
fn、引数リスト、=>、1つの式の順に書きます。引数の型、デフォルト値、戻り値の型は通常の関数と同じように使えます。
returnキーワードも波括弧もありません。長い式も、読みやすさのために複数行に分けられます。
外側の変数は値でキャプチャされる
アロー関数は、作られたスコープのすべての変数を参照できます。その時点の値をコピーするので、中での変更は中にとどまり、関数を作ったあとの外での変更は見えません。
これが、変数を参照で共有できるfunction () use (&$count)との大きな違いです。アロー関数は外側の変数に再代入できません。ただし、キャプチャしたオブジェクトは変更できます(コピーは同じオブジェクトへのハンドルだからです)。また参照として宣言した引数は、どの関数とも同じように動きます:fn(array &$list) => $list[] = 'x'。
array_map、array_filter、usortのコールバック
ほとんどの配列関数はコールバックを受け取り、アロー関数がいちばん記述を減らしてくれるのはそこです。同じ絞り込みを両方の書き方で比べてみましょう。
<=>は-1、0、1を返し、これはusort()が求めるものそのものなので、フィールドでの並べ替えが1行に収まります。降順にするには$aと$bを入れ替えます。
アロー関数を返すアロー関数
キャプチャされる変数には外側のアロー関数の引数も含まれるので、ネストしてほかの値から関数を作れます。
array_filter()は元のキーを保つので、結果が添字1から始まっている点に注意してください。
fnとfunction:完全なクロージャが必要なとき
本体に複数の式が必要なときや、外側の変数を変更しなければならないとき、アロー関数は使えません。そのときは無名関数を使います。
fn($x) => ... | function ($x) use ($y) { ... } | |
|---|---|---|
| 本体 | 1つの式 | 任意の文 |
| 戻り値 | 自動 | 明示的なreturn |
| 外側の変数 | 使ったものすべてを自動で | useに並べたものだけ |
| 参照でキャプチャ | できない | できる、use (&$y) |
| 使えるようになった版 | PHP 7.4 | PHP 5.3 |
アロー関数が窮屈に感じるときは、たいていその処理が2つの処理であることを意味しています。上のように絞り込みと合計に分ければ、各コールバックを1つの式に保てます。
よくある質問
PHPのアロー関数とは何ですか?
PHP 7.4で導入された短い無名関数です:fn($x) => $x * 2。本体は1つの式で、その値が自動的に返され、use句なしで周りのスコープの変数を読めます。
PHPのアロー関数は複数行にできますか?
できません。=>のあとの本体は1つの式でなければならず、文を並べるブロックはありません。長い式を複数行に分けることはできますが、if、ループ、複数の文が必要なら、代わりにfunction () use (...) { ... }を使います。
アロー関数は外側の変数を変更できますか?
できません。アロー関数は外側の変数を値でキャプチャするので、fn() => $count++は自分のコピーを変えるだけで、外側の$countはそのままです。外側の変数を変更するには、use (&$count)を付けたクロージャを使います。
PHPのfnとfunctionの違いは何ですか?
fn($x) => ...は1つの式を持ち、それを暗黙に返し、使う外側の変数をすべて値でキャプチャします。function ($x) use ($y) { ... }はどんな文でも持て、明示的なreturnが必要で、useに並べた変数だけが見え、それらは参照でキャプチャすることもできます。