array_map($callback, $array)は、$arrayのすべての要素に対して$callbackを呼び出し、結果を新しい配列で返します。コールバックが先、配列が後で、元の配列は変わりません。
fn($p) => $p * 1.2はアロー関数で、1つの式の結果を返す関数です。代わりにどんなcallableでも使えます。
組み込み関数をコールバックに使う
組み込み関数の名前を文字列で渡します。配列全体をきれいにするいちばん短い方法で、すべての値をtrimしたり、文字列を整数に変換したり、大文字小文字を変えたりできます。
array_map('intval', ...)は、フォームやexplode()から来た文字列を本物の整数にする定番の方法です。PHP 8.1のファーストクラスcallable構文でintval(...)と書くこともでき、エディターが補完やチェックをしてくれます。
外側の変数を使うクロージャ
アロー関数は周りの変数を自動で参照できます。従来のfunctionでは、useで取り込む必要があります。どちらも無名関数のページで説明しています。
キー付きのarray_map
配列が1つなら、array_mapは文字列キーも含めてキーを保ちます。ただし、コールバックが受け取るのは値だけです。キーも取得するには、array_keys($array)を2つ目の配列として渡します。すると、コールバックは各配列から1つずつ要素を受け取って呼ばれます。
2つ目の結果に注目してください。複数の配列を渡したとたん、キーは0, 1, 2に置き換わります。最後の行でarray_combine()を使ってキーを作り直しているのはそのためです。
複数の配列を同時に処理する
追加した配列はそれぞれコールバックの追加の引数になり、位置で対応づけられます。配列の長さが違うと、短いほうはnullで埋められます。
コールバックにnullを渡すと関数を呼ばず、配列をペアにまとめます。
array_map、array_walk、foreachの違い
array_mapは新しい配列を作ります。array_walkは渡した配列を参照を通して変更し、コールバックの2つ目の引数としてキーを渡します。foreachはどちらもでき、要素を飛ばしたりbreakで早めに止めたりもできます。
すべての要素がちょうど1つの新しい要素になるならarray_mapを使います。一部の要素を取り除く必要もあるなら、array_filterと組み合わせるか、foreachを書きます。
よくあるミス:引数の順番
array_mapはコールバックが先で配列が後です。隣のarray_filterは逆の順番なので、混同しやすくなっています。
array_map($callback, $array); // callback first
array_filter($array, $callback); // array first
入れ替えると、普通の配列は正しいコールバックではないので、PHP 8はTypeErrorを投げます。
PHPは次のように止まります。
PHP Fatal error: Uncaught TypeError: array_map(): Argument #1 ($callback) must be a valid callback or null, array callback must have exactly two members in /home/index.php:4
2つの引数を入れ替え直せば、ブロックは動きます。
よくある質問
PHPのarray_mapは何をしますか?
配列のすべての要素に対して関数を呼び出し、結果を新しい配列で返します:array_map(fn($n) => $n * 2, [1, 2, 3])は[2, 4, 6]を返します。元の配列は変わりません。
array_mapはキーを保ちますか?
配列が1つなら保ちます。文字列キーも整数キーもそのままです。配列が2つ以上なら、結果には常に新しいキー0, 1, 2...が振られます。
array_mapのコールバックの中でキーを取得するには?
キーを2つ目の配列として渡します:array_map(fn($k, $v) => "$k=$v", array_keys($arr), $arr)。結果はリストになるので、元のキーが必要ならarray_combine(array_keys($arr), ...)で包みます。
array_mapはforeachより速いですか?
意味のある差はありません。どちらも配列を1回ループし、要素ごとの関数呼び出しがない分、素のforeachのほうが少し速いことがよくあります。新しい配列を作る1つの変換のように、読みやすくなるときにarray_mapを選びましょう。
array_mapとarray_walkの違いは何ですか?
array_mapは新しい配列を返し、入力はそのままにします。array_walkはtrueを返し、参照の引数を通して配列をその場で変更するためのものです:array_walk($arr, function (&$v, $k) { $v = trim($v); });。