PHPのarray_walk関数の使い方!配列の各要素にユーザー定義関数を適用

PHPのarray_walk関数は、配列の各要素に対して、ユーザーが定義したコールバック関数を適用するために使用されます。

この関数は、配列の要素を直接変更したり、各要素に対して特定の処理(例: データベースへの書き込み、ログ出力)を発生させたりする場合に特に役立ちます。
array_mapが新しい配列を返すのに対し、array_walkは元の配列の要素を直接操作できる点が大きな特徴です。

この記事では、array_walk 関数の基本的な使い方、引数、戻り値、参照渡しによる要素の変更、ユーザーデータの渡し方、そして使用する際の注意点に解説します。

array_walk関数の基本的な構文

array_walk 関数の基本的な構文は以下の通りです。

array_walk(array &$array, callable $callback, mixed $userdata = null):bool
  • $array: 処理対象となる配列です。この配列は参照渡し(& 記号)されるため、コールバック関数内で要素を変更すると元の配列が直接変更されます
  • $callback: 各配列要素に適用するコールバック関数です。このコールバック関数は、以下の引数を受け取ります。
    1. $value: 現在処理中の配列要素の値。
    2. $key: 現在処理中の配列要素のキー。
    3. $userdata: オプション。array_walk の第3引数で渡されたユーザーデータ。
  • $userdata: オプション。$callback 関数の第3引数に渡したい任意のデータです。

array_walk関数の戻り値

処理が成功した場合は true、失敗した場合は false が返されます。

array_walk関数を使ってみる

array_walk関数を実際に使って、動作を確認します。

例1:各要素の値を表示する

最も基本的な使い方です。
各要素の値とキーを表示します。

<?php
$fruits = ['apple', 'banana', 'orange'];

array_walk($fruits, function($value, $key) {
    echo "キー: {$key}, 値: {$value}" . PHP_EOL;
});
// 出力:
// キー: 0, 値: apple
// キー: 1, 値: banana
// キー: 2, 値: orange
?>

$fruits配列を作っています。
次の処理で、array_walk関数を使って、配列の内容を出力しています。

第1引数に配列を渡して、第2引数の無名関数で処理しています。
関数の$value変数に値が入って、$keyにキーが入ってきます。

結果、値とキーが出力されることが確認できました。

例2:連想配列の要素を表示する

連想配列のキーもコールバック関数に渡されます。

<?php
$user = [
    'name' => 'Alice',
    'age' => 30,
    'city' => 'New York'
];

array_walk($user, function($value, $key) {
    echo "{$key}: {$value}" . PHP_EOL;
});
// 出力(連想配列でもキーと値を取得できます):
// name: Alice
// age: 30
// city: New York
?>

連想配列にたいして、array_walk関数を使っています。
$keyに連想配列のキーが入って、$valueに値が入ってくることが確認できました。

参照渡しによる要素の変更

array_walkの最も強力な特徴のひとつは、コールバック関数の第1引数(要素の値)を参照渡しにできることです。
そのため、元の配列の要素を直接変更できます。

例1:各数値を2倍にする (元の配列を変更)

array_walk関数の値を参照渡しにすることで、配列の内容を変更してみます。

<?php
$numbers = [1, 2, 3, 4, 5];

array_walk($numbers, function(&$value, $key) { // $value を参照渡しにする (&)
    $value = $value * 2;
});

print_r($numbers);
// 出力:
// Array
// (
//     [0] => 2
//     [1] => 4
//     [2] => 6
//     [3] => 8
//     [4] => 10
// )
?>

array_walk関数の$valueの前に&を付けています。
こうすることで、コールバック関数内で$valueを変更すると、元の$numbers配列の対応する要素が直接更新されます。

例2:文字列のトリムと大文字化 (元の配列を変更)

同様に配列の文字列に対しても、参照渡しを使用してみました。

<?php
$items = ['  apple  ', ' BANANA ', 'orange '];

array_walk($items, function(&$value, $key) {
    $value = trim($value);
    $value = strtoupper($value);
});

print_r($items);
// 出力:
// Array
// (
//     [0] => APPLE
//     [1] => BANANA
//     [2] => ORANGE
// )
?>

文字列の配列$itemsarray_walk関数に渡しています。
&$valueで参照渡しにして、関数の中で、余白の削除と大文字に変換しています。

出力結果を確認すると、元の文字列の余白が消えて、大文字になっていることが確認できます。

ユーザーデータの渡し方

array_walk関数の第3引数$userdataを使用すると、コールバック関数に任意の追加データを渡すことができます。

例1:ユーザーデータを使って要素を処理する

通常は「値」と「キー」の2つを処理しますが、必要に応じて「追加データ」も一緒に渡せます。
ユーザーデータをコールバック関数に渡して処理をしています。

<?php
$products = [
    ['name' => 'Laptop', 'price' => 1200],
    ['name' => 'Mouse', 'price' => 25],
    ['name' => 'Keyboard', 'price' => 80]
];

$currencySymbol = '$';

array_walk($products, function(&$product, $key, $symbol) {
    $product['formatted_price'] = $symbol . $product['price'];
}, $currencySymbol); // $currencySymbol を $userdata として渡す

print_r($products);
// 出力:
// Array
// (
//     [0] => Array ( [name] => Laptop [price] => 1200 [formatted_price] => $1200 )
//     [1] => Array ( [name] => Mouse [price] => 25 [formatted_price] => $25 )
//     [2] => Array ( [name] => Keyboard [price] => 80 [formatted_price] => $80 )
// )
?>

最初に多次元配列の$products配列を用意しました。
ユーザーデータとして文字列の「$」を渡しています。

array_walkの第3引数に渡して、コールバック関数の第3引数で受け取っています。
そして、配列の値段(キーがprice)の値に対して、$マークをつけて、新しいキーformatted_priceをつけて配列に入れています。

配列を出力すると、新しくフォーマットされた値段が追加されていることが確認できました。

array_walk関数を使う際の注意点

array_walk関数を使う際の注意点です。

元の配列が変更される可能性がある

コールバック関数の第1引数を参照渡し (&) にした場合、元の配列が直接変更されます。
この性質を理解して使用する必要があります。

多次元配列の扱い

array_walk関数は、デフォルトでは多次元配列の深層まで再帰的に処理しません。
多次元配列のすべての要素を処理したい場合は、array_walk_recursive関数を使用する必要があります。

戻り値はbool

array_walk関数自体の戻り値は、処理が成功したかどうかを示す true または false です。
コールバック関数が返した値はarray_walk関数の戻り値には影響しません。

配列の構造変更

コールバック関数内で配列の要素を追加したり削除したりすると、予期せぬ結果になる可能性があります。
array_walk関数は、反復処理中に配列の構造が変更されることを想定していません。

要素の追加や削除が必要な場合は、foreachループや array_spliceなどの他の方法を検討してください。

array_walkとforeach / array_mapの違い

機能 array_walk foreachループ array_map
用途 元の配列の要素を直接操作/副作用 配列の各要素に処理を行う (結果を新しい配列に格納することも可能) 新しい配列を生成する (変換、整形)
戻り値 true または false (処理が成功したか) なし (直接操作または別の配列に代入) 新しい配列
キーの保持 する する しない (常に数値インデックス)
多次元配列 デフォルトでは深層まで処理しない (array_walk_recursive を使用) サポートする サポートしない (ネストした配列は個別に処理が必要)
柔軟性 キーや値、ユーザーデータをコールバックに渡せる 非常に柔軟 簡潔だが、特定の目的に特化している

使い分けの目安

  • array_walk: 配列の各要素に対して直接変更を加えたい場合や、各要素に対して特定の副作用を発生させたい場合に最適です。キーも利用したい場合に便利です。
  • foreachループ: 最も汎用性が高く、配列の要素を直接操作したい場合や、キーを保持したい場合、複雑なロジックが必要な場合に適しています。array_walk よりも柔軟な制御が可能です。
  • array_map: 配列の各要素を変換・加工して、新しい配列が欲しい場合に最適です。元の配列は変更されません。

まとめ

PHPのarray_walk関数は、配列の各要素に対してユーザー定義関数を適用することができました。
元の配列の要素を直接変更したり、各要素に対して特定の処理を発生させたりする際に非常に強力です。

また、キーやユーザーデータをコールバック関数に渡せる柔軟性も持ち合わせています。
参照渡しによる要素の変更、多次元配列の扱い、そしてforeacharray_map関数との使い分けを理解して、array_walk関数を効果的に活用し、より効率的で読みやすいPHPコードを作成しましょう。

PHP

コメント