1. ホーム
  2. PHP

【PHP】array_walk の使い方|配列の各要素にコールバックを適用して書き換える

Share

配列のすべての要素に同じ処理を行いたいとき、foreach でループを書く方法のほかに、array_walk という関数を使う方法があります。array_walk は各要素に対して用意した処理(コールバック関数)を順番に適用してくれる関数で、参照渡しを使えば元の配列そのものを書き換えることもできます。この記事では、array_walk の基本の使い方から、要素の書き換え、array_map との違い、つまずきやすい点までを、実際に動くコード付きで解説します。

array_walk とは

array_walk は、配列の各要素に対してコールバック関数を1回ずつ呼び出す関数です。コールバックには値とキーが渡されるので、要素の内容を使った処理を書けます。戻り値は成功したかどうかの真偽値で、処理結果は(後述する参照渡しを通じて)元の配列に反映されます。まずは各要素を順番に出力する、最小の例を見てみましょう。

example.php
<?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引数だけ書いても構いません。

example.php
<?php
array_walk($配列, function ($値, $キー) {
    // 各要素に対して行う処理
});

参照渡しで元の配列を書き換える

array_walk の便利なところは、コールバックの値の引数を参照渡し&$value)にすると、元の配列の要素をその場で書き換えられる点です。頭に & を付けるかどうかで挙動が大きく変わります。次の例では、すべての価格を税込み(1.1倍)に更新しています。

example.php
<?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引数として毎回渡されます。外から共通の設定や接尾辞などを渡したいときに使います。

example.php
<?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_walkarray_map
戻り値真偽値(成功で true)処理後の新しい配列
元の配列参照渡しで書き換えられる変更しない
キーの扱いコールバックにキーが渡る基本はキーを渡さない
向いている場面元の配列を直接更新したい変換後の配列を新しく作りたい

使い分けの目安として、元の配列を書き換えたい・キーを使いたいなら array_walk元は残して変換後の新しい配列がほしいなら array_map を選ぶとよいでしょう。

要素の追加・削除やキーの変更はできない

array_walk でできるのは、あくまで各要素の値を書き換えることまでです。ループの途中で要素を増やしたり減らしたり、キーそのものを変更したりはできません(コールバックのキー引数は読み取り用で、書き換えても元のキーには反映されません)。要素の数を変えたい場合は array_filter で絞り込む、キーを付け替えたい場合は array_combineforeach で新しい配列を組み立てる、といった別の方法を使います。array_walk は「各要素をその場で加工する」ための関数、と役割を絞って考えると使いどころが見えてきます。

まとめ

array_walk は、配列の各要素にコールバックを適用する関数です。コールバックには値とキーが渡り、値を &$value と参照で受け取れば元の配列をその場で書き換えられます。第3引数を使えば外部の値をコールバックに渡すこともできます。新しい配列を返す array_map とは目的が異なり、array_walk は「元の配列を直接更新する」用途に向いています。要素の増減やキーの変更はできない点だけおさえておけば、配列の一括加工をシンプルに書けるようになります。

参考ページ