配列のすべての要素に同じ処理を行いたいとき、foreach でループを書く方法のほかに、array_walk という関数を使う方法があります。array_walk は各要素に対して用意した処理(コールバック関数)を順番に適用してくれる関数で、参照渡しを使えば元の配列そのものを書き換えることもできます。この記事では、array_walk の基本の使い方から、要素の書き換え、array_map との違い、つまずきやすい点までを、実際に動くコード付きで解説します。
目次
array_walk とは
array_walk は、配列の各要素に対してコールバック関数を1回ずつ呼び出す関数です。コールバックには値とキーが渡されるので、要素の内容を使った処理を書けます。戻り値は成功したかどうかの真偽値で、処理結果は(後述する参照渡しを通じて)元の配列に反映されます。まずは各要素を順番に出力する、最小の例を見てみましょう。
<?php
$fruits = ['apple', 'banana', 'cherry'];
// 各要素に対してコールバックが呼ばれる(値, キー の順で渡る)
array_walk($fruits, function ($value, $key) {
echo "{$key}: {$value}\n";
});
// 0: apple
// 1: banana
// 2: cherry
基本の書き方とコールバックの引数
呼び出しの形は次のとおりです。第1引数に対象の配列、第2引数にコールバック関数を渡します。コールバックは第1引数に値、第2引数にキーを受け取ります。キーが不要なら第1引数だけ書いても構いません。
<?php
array_walk($配列, function ($値, $キー) {
// 各要素に対して行う処理
});
参照渡しで元の配列を書き換える
array_walk の便利なところは、コールバックの値の引数を参照渡し(&$value)にすると、元の配列の要素をその場で書き換えられる点です。頭に & を付けるかどうかで挙動が大きく変わります。次の例では、すべての価格を税込み(1.1倍)に更新しています。
<?php
$prices = [100, 200, 300];
// 値を参照(&$value)で受け取ると、元の配列を直接書き換えられる
array_walk($prices, function (&$value) {
$value = (int) round($value * 1.1); // 税込みにする
});
print_r($prices); // [110, 220, 330]
もし & を付け忘れて function ($value) と書くと、書き換えているのはコールバック内のコピーだけになり、元の $prices は変わりません。「配列を書き換えたいのに反映されない」というときは、まずこの & の有無を確認しましょう。
第3引数で追加のデータを渡す
array_walk の第3引数に値を渡すと、その値がコールバックの第3引数として毎回渡されます。外から共通の設定や接尾辞などを渡したいときに使います。
<?php
$names = ['taro', 'hanako'];
// 第3引数の ' さん' が、コールバックの $suffix に渡る
array_walk($names, function (&$value, $key, $suffix) {
$value = $value . $suffix;
}, ' さん');
print_r($names); // ['taro さん', 'hanako さん']
array_map との違いと使い分け
要素を1つずつ処理するという点では array_map と似ていますが、目的と挙動が異なります。array_map は処理結果を新しい配列として返す関数で、元の配列は変更しません。一方 array_walk は元の配列をその場で書き換えるのが得意で、戻り値は真偽値です。主な違いをまとめます。
| 観点 | array_walk | array_map |
|---|---|---|
| 戻り値 | 真偽値(成功で true) | 処理後の新しい配列 |
| 元の配列 | 参照渡しで書き換えられる | 変更しない |
| キーの扱い | コールバックにキーが渡る | 基本はキーを渡さない |
| 向いている場面 | 元の配列を直接更新したい | 変換後の配列を新しく作りたい |
使い分けの目安として、元の配列を書き換えたい・キーを使いたいなら array_walk、元は残して変換後の新しい配列がほしいなら array_map を選ぶとよいでしょう。
要素の追加・削除やキーの変更はできない
array_walk でできるのは、あくまで各要素の値を書き換えることまでです。ループの途中で要素を増やしたり減らしたり、キーそのものを変更したりはできません(コールバックのキー引数は読み取り用で、書き換えても元のキーには反映されません)。要素の数を変えたい場合は array_filter で絞り込む、キーを付け替えたい場合は array_combine や foreach で新しい配列を組み立てる、といった別の方法を使います。array_walk は「各要素をその場で加工する」ための関数、と役割を絞って考えると使いどころが見えてきます。
まとめ
array_walk は、配列の各要素にコールバックを適用する関数です。コールバックには値とキーが渡り、値を &$value と参照で受け取れば元の配列をその場で書き換えられます。第3引数を使えば外部の値をコールバックに渡すこともできます。新しい配列を返す array_map とは目的が異なり、array_walk は「元の配列を直接更新する」用途に向いています。要素の増減やキーの変更はできない点だけおさえておけば、配列の一括加工をシンプルに書けるようになります。