基礎

PHPのアロー関数|fn式で簡潔に書く無名関数

PHPのアロー関数(Arrow Function)は、PHP 7.4で導入された短い構文の無名関数です。fn キーワードを使い、1つの式を返す短い関数を簡潔に記述できます。

従来のクロージャでは use で外部変数を明示的に取り込む必要がありましたが、アロー関数では外部変数が自動的にキャプチャされます。コールバック処理がさらにスッキリ書けるようになりました。

基本的な使い方

fn(引数) => 式 の形式で定義します。=> の後に書いた式の結果が自動的に返されます。

PHP
<?php
// アロー関数
$double = fn($n) => $n * 2;

echo $double(5) . "\n";
echo $double(12) . "\n";

// 従来のクロージャとの比較
$doubleClosure = function($n) {
    return $n * 2;
};

echo $doubleClosure(5) . "\n";
実行結果
10
24
10

アロー関数は return を書く必要がなく、1行で記述できます。複数行の処理が必要な場合は従来のクロージャを使います。

外部変数の自動キャプチャ

アロー関数の最大の特徴は、外部変数が use なしで自動的にキャプチャされることです。

PHP
<?php
$taxRate = 0.10;

// アロー関数:useなしで$taxRateにアクセス可能
$calcTax = fn($price) => $price * (1 + $taxRate);

// 従来のクロージャ:useが必要
$calcTaxOld = function($price) use ($taxRate) {
    return $price * (1 + $taxRate);
};

echo $calcTax(1000) . "\n";
echo $calcTaxOld(1000) . "\n";
実行結果
1100
1100

アロー関数での変数キャプチャは常に値渡しです。参照渡しでのキャプチャはできないため、外部変数を変更したい場合は従来のクロージャを使う必要があります。

配列操作での活用

アロー関数は array_map()array_filter() で特に威力を発揮します。

PHP
<?php
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 各要素を2乗
$squared = array_map(fn($n) => $n ** 2, $numbers);
echo implode(", ", $squared) . "\n";

// 偶数のみフィルタ
$evens = array_filter($numbers, fn($n) => $n % 2 === 0);
echo implode(", ", $evens) . "\n";

// 合計が一定以上の要素をフィルタ
$threshold = 5;
$above = array_filter($numbers, fn($n) => $n > $threshold);
echo implode(", ", $above) . "\n";
実行結果
1, 4, 9, 16, 25, 36, 49, 64, 81, 100
2, 4, 6, 8, 10
6, 7, 8, 9, 10

型宣言との組み合わせ

アロー関数にも型宣言を付けることができます。

PHP
<?php
$toInt = fn(string $s): int => (int)$s;
$concat = fn(string $a, string $b): string => $a . $b;

echo $toInt("42") . "\n";
echo $concat("Hello", " World") . "\n";
実行結果
42
Hello World

実用的な例

PHP
<?php
// ネストしたアロー関数
$addFactory = fn($x) => fn($y) => $x + $y;

$add5 = $addFactory(5);
echo $add5(3) . "\n";   // 8
echo $add5(10) . "\n";  // 15

// 連想配列のソートキー指定
$users = [
    ["name" => "田中", "score" => 85],
    ["name" => "佐藤", "score" => 92],
    ["name" => "鈴木", "score" => 78],
];

usort($users, fn($a, $b) => $b["score"] - $a["score"]);
foreach ($users as $u) {
    echo "{$u['name']}: {$u['score']}点\n";
}

// 配列からプロパティだけ抽出
$names = array_map(fn($u) => $u["name"], $users);
echo "名前一覧: " . implode(", ", $names) . "\n";
実行結果
8
15
佐藤: 92点
田中: 85点
鈴木: 78点
名前一覧: 佐藤, 田中, 鈴木
クロージャとの使い分け

アロー関数は1つの式のみを返す短い処理に向いています。複数行の処理、use による参照渡し、または副作用を伴う処理には従来のクロージャを使いましょう。短い処理ならアロー関数、複雑な処理ならクロージャ、という使い分けが基本です。

注意

アロー関数は波括弧 {} を使った複数文のブロックをサポートしません。fn($x) => { ... } のように書くとエラーになります。また、PHP 7.4未満では使用できないため、サーバーのPHPバージョンを確認してください。

まとめ

  • fn(引数) => 式 で短い無名関数を定義できる(PHP 7.4+)
  • 外部変数は use なしで自動キャプチャされる(値渡しのみ)
  • array_map()array_filter() のコールバックに最適
  • 型宣言やネストも可能で、関数型スタイルのコードが書きやすい
  • 複数行の処理や参照渡しが必要な場合は従来のクロージャを使う