【PHP8.x】array_walk_recursive関数の使い方
array_walk_recursive関数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
array_walk_recursive関数は、指定された多次元配列のすべての要素に対して、ユーザー定義のコールバック関数を再帰的に適用する関数です。この関数は、配列の最も深い階層にある要素までを順番に処理します。
第一引数には処理対象となる配列を指定します。この配列の要素は、コールバック関数内で値を変更することも可能です。第二引数には、各配列要素に適用したい処理を定義したコールバック関数を指定します。このコールバック関数は、通常、現在の要素の値とキーの二つの引数を受け取ります。
さらに、オプションで第三引数を指定することも可能です。この第三引数は、コールバック関数に固定の追加データを渡したい場合に利用します。コールバック関数は、最初の二つの引数に加えて、この追加データを第三の引数として受け取ることができます。
この関数は、配列のすべての要素に特定の処理を一括して行いたい場合や、多次元配列の内容を走査して何らかの操作をしたい場合に非常に便利です。たとえば、配列内のすべての文字列を大文字に変換したり、特定の条件を満たす要素に対してログを出力したりする用途に活用できます。
処理が成功した場合はtrueを返し、何らかの問題が発生して処理が失敗した場合はfalseを返します。この関数を使用することで、複雑なループ処理を記述することなく、簡潔に多次元配列の要素操作を行うことができます。
構文(syntax)
1<?php 2$data_array = [ 3 "category_a" => [ 4 "item_a1", 5 "item_a2", 6 ], 7 "category_b" => [ 8 "item_b1", 9 "item_b2", 10 ], 11 "some_value" => 123 12]; 13 14$user_context = "Processed-"; 15 16array_walk_recursive($data_array, function (&$value, $key, $context) { 17 if (is_string($value)) { 18 $value = $context . strtoupper($value); 19 } 20}, $user_context); 21 22print_r($data_array); 23?>
引数(parameters)
array &$array, callable $callback, mixed $arg = null
- array & $array: 操作対象の配列。配列は参照渡しされるため、関数内で変更された値が元の配列に反映されます。
- callable $callback: 配列の各要素に対して実行されるコールバック関数。この関数は、配列のキー、値、そしてオプションの引数を受け取ります。
- mixed $arg = null: コールバック関数に渡されるオプションの引数。デフォルトはnullです。
戻り値(return)
bool
array_walk_recursive関数は、配列の全要素(ネストされた配列の要素も含む)に対してユーザー定義関数を適用する際に、処理が成功したかどうかを示すboolean値を返します。処理が成功した場合はTRUE、失敗した場合はFALSEを返します。
サンプルコード
PHP array_walk_recursive で多次元配列を処理する
1<?php 2 3/** 4 * 多次元配列内の特定のキーを持つ値を再帰的にマスキングする関数です。 5 * 6 * このサンプルは、array_walk_recursive を使用して、階層の深さに関わらず、 7 * 配列の末端にある全ての要素をチェックし、条件に一致する値を変更する方法を示します。 8 * システム設定ファイルなどから機密情報をログ出力前に隠す、といった実用的な例です。 9 */ 10function maskSensitiveDataExample(): void 11{ 12 // ユーザープロファイルとシステム設定を含む多次元配列 13 $data = [ 14 'user_profile' => [ 15 'username' => 'alice', 16 'password' => 'S3cr3tP@ssw0rd!', // マスキングしたい値 17 'contact' => [ 18 'email' => 'alice@example.com', 19 'phone' => '090-1234-5678', 20 ], 21 ], 22 'system_config' => [ 23 'database' => [ 24 'dsn' => 'mysql:host=localhost;dbname=testdb', 25 'db_password' => 'AnotherS3cr3t!', // マスキングしたい値 26 ], 27 'api_key' => 'abcdef1234567890', // マスキングしたい値 28 ], 29 'log_level' => 'debug', 30 ]; 31 32 echo "--- 処理前のデータ ---" . PHP_EOL; 33 print_r($data); 34 35 /** 36 * 配列の各要素に適用されるコールバック関数です。 37 * 38 * @param mixed &$value 要素の値。参照渡し(&)のため、この関数内での変更は元の配列に直接反映されます。 39 * @param string|int $key 要素のキー。 40 */ 41 $maskingCallback = function (mixed &$value, string|int $key): void { 42 // キー名に 'password' または 'key' が含まれているかチェックします。 43 // is_stringでキーが文字列であることも確認し、安全性を高めます。 44 if (is_string($key) && (str_contains($key, 'password') || str_contains($key, 'key'))) { 45 // 条件に一致した場合、値を固定の文字列で上書きします。 46 $value = '********'; 47 } 48 }; 49 50 // array_walk_recursive を実行して、配列内のデータを再帰的に処理します。 51 // 第1引数に処理対象の配列(参照渡し)、第2引数にコールバック関数を指定します。 52 array_walk_recursive($data, $maskingCallback); 53 54 echo PHP_EOL . "--- 処理後のデータ ---" . PHP_EOL; 55 print_r($data); 56} 57 58// サンプル関数を実行します。 59maskSensitiveDataExample();
array_walk_recursiveは、多次元配列のすべての要素(配列の末端にある値)に対して、指定した処理を再帰的に実行するためのPHP関数です。階層の深さに関わらず、配列内のすべての値に対して一括で処理を行いたい場合に非常に便利です。
このサンプルコードは、ユーザー情報やシステム設定が混在した多次元配列 $data を対象に、'password' や 'api_key' といった機密情報を含む値を、安全な固定文字列 '********' に置き換える処理を示しています。
関数の第1引数には、処理対象の配列 $data を指定します。この引数は参照渡し(&)であるため、後述するコールバック関数内で要素の値を変更すると、元の $data 配列が直接書き換えられます。
第2引数には、配列の各要素に適用する処理内容を定義したコールバック関数 $maskingCallback を渡します。このコールバック関数は、要素の値 $value とキー $key を引数として受け取ります。$value も参照渡しになっており、サンプルではキー名に特定の文字列が含まれているかを判定し、条件に一致した場合にこの $value の値を上書きしています。
この関数は処理が成功すると true を返しますが、このサンプルのように元の配列を直接変更することが主目的の場合、戻り値は利用されないこともあります。
array_walk_recursiveは、第一引数で渡した配列を直接変更します。処理前のデータを残したい場合は、実行前に配列をコピーしてください。コールバック関数内で値を変更するには、第一引数を&$valueのように参照渡しで受け取る必要があります。この&を忘れると、元の配列の値は更新されません。この関数が処理するのは多次元配列の末端にある値のみで、途中の配列自体は対象外となる点にも注意が必要です。また、キー名で条件を判定する際は、サンプルにあるようにis_stringなどで型を確認すると、意図しない動作を防ぐことができます。
array_walk_recursiveでネスト要素を処理する
1<?php 2 3/** 4 * Demonstrates the usage of array_walk_recursive to process all elements 5 * in a multi-dimensional array. 6 * 7 * This function iterates through all values of an array, including nested arrays, 8 * and applies a transformation to string values by appending their immediate key. 9 * 10 * Note on "parent key": The callback function for array_walk_recursive 11 * receives only the current element's key, not the keys of its parent arrays 12 * in the hierarchy. This example's comments address this specific point. 13 * 14 * @param array $data The input multi-dimensional array. 15 * @return array The array with string values modified. 16 */ 17function processArrayElementsRecursively(array $data): array 18{ 19 // It's good practice to work on a copy if the original array should not be modified directly 20 // If modification of the original array is desired, pass $data by reference: array &$data 21 $processedData = $data; 22 23 // array_walk_recursive calls the provided callback function for each scalar value 24 // within the array, including those in nested arrays. 25 // The $value is passed by reference (&), allowing its modification within the array. 26 // The $key is the key of the current element. 27 array_walk_recursive( 28 $processedData, 29 function (&$value, $key) { 30 // Example: Append the current key to string values. 31 // This demonstrates what information (value and current key) is available. 32 if (is_string($value)) { 33 $value .= " [Current Key: $key]"; 34 } 35 36 // IMPORTANT NOTE for 'parent key' keyword: 37 // The array_walk_recursive callback function does NOT provide direct 38 // access to the parent key(s) or the full path of the current element 39 // within the multi-dimensional array structure. 40 // If parent key context or a full path is required, a custom 41 // recursive function that manually tracks the path is typically needed. 42 } 43 ); 44 45 return $processedData; 46} 47 48// --- Example Usage --- 49 50// A sample multi-dimensional array for demonstration 51$myArray = [ 52 'user_info' => [ 53 'profile' => [ 54 'name' => 'Alice Smith', 55 'email' => 'alice@example.com' 56 ], 57 'contact' => [ 58 'phone' => '123-456-7890', 59 'address' => '123 Main St' 60 ] 61 ], 62 'app_settings' => [ 63 'version' => '1.0.0', 64 'debug_mode' => true 65 ] 66]; 67 68echo "Original Array:\n"; 69print_r($myArray); 70 71// Process the array using our function 72$modifiedArray = processArrayElementsRecursively($myArray); 73 74echo "\nModified Array (string values show their current key):\n"; 75print_r($modifiedArray); 76 77?>
array_walk_recursiveは、PHPで多次元配列のすべての要素(スカラー値)を再帰的に処理するための関数です。配列の深さにかかわらず、それぞれの値に対して指定されたコールバック関数を実行できます。
この関数の第一引数&$arrayには処理対象の多次元配列を渡します。参照渡しのため、コールバック関数内で値を変更すると元の配列の内容も更新されます。第二引数callable $callbackは、各要素に対して実行される関数を指定します。このコールバック関数は、現在の要素の値とキーを引数として受け取ります。具体的には、function (&$value, $key) の形式で、$valueも参照渡しで渡されるため、コールバック内で値を変更できます。第三引数mixed $argはオプションで、コールバック関数に3番目の引数として渡すことができます。関数が成功した場合はtrue、失敗した場合はfalseを返しますが、通常はtrueが返されます。
サンプルコードでは、processArrayElementsRecursively関数内でarray_walk_recursiveを使用し、多次元配列内のすべての文字列値に、その要素自身のキーを追記しています。これは、コールバック関数に渡される$keyが、現在処理している要素の直接のキーであることを示すための例です。
ここで重要な注意点として、「parent key」について説明します。array_walk_recursiveのコールバック関数は、現在処理中の要素のキー ($key) は提供しますが、その要素が配列階層内でどの親キーの下にあるか、といった情報(親のキーや完全なパス)は直接提供しません。もし親のキーなどの情報が必要な場合は、array_walk_recursiveではなく、独自の再帰関数を記述してパスを追跡する必要があります。
このように、array_walk_recursiveは多次元配列内のスカラー値を一括処理する際に非常に便利ですが、親要素のコンテキストが必要な場合は別途考慮が必要です。
array_walk_recursive関数は、多次元配列のすべてのスカラー値に対し、指定されたコールバック関数を再帰的に実行します。コールバック関数には現在の要素の値とキーが渡され、値を参照渡し(&$value)にすることで、元の配列の要素を直接変更できます。
特に注意が必要な点は、コールバック関数には現在の要素のキーは渡されますが、その親のキーや配列内での完全なパスは直接提供されないことです。もし親のキーや完全なパスの情報が必要な場合は、この関数ではなく、パスを追跡する独自の再帰関数を実装する必要があります。
引数に渡す配列を直接変更したくない場合は、サンプルコードのように関数内で配列をコピーしてからarray_walk_recursiveを使用することをお勧めします。これにより、元のデータへの意図しない変更を防ぎ、コードをより安全に保つことができます。
array_walk_recursive の処理結果を確認する
1<?php 2 3/** 4 * array_walk_recursive() 関数によって、配列の各要素に適用されるコールバック関数。 5 * この関数は、文字列型の要素を大文字に変換します。 6 * array_walk_recursive のコールバックは通常、次の引数を取ります。 7 * - &$value: 現在の要素の値(参照渡しで変更可能) 8 * - $key: 現在の要素のキー 9 * - $userdata: array_walk_recursive に渡されたオプションの引数(ここでは未使用) 10 * 11 * @param mixed $value 配列の現在の要素の値(参照渡し) 12 * @param mixed $key 配列の現在の要素のキー 13 * @return void 14 */ 15function convertValueToUppercase(mixed &$value, mixed $key): void 16{ 17 // 要素が文字列型の場合のみ、大文字に変換します 18 if (is_string($value)) { 19 $value = strtoupper($value); 20 echo "キー: '{$key}', 値: '{$value}' に変換しました。\n"; 21 } 22} 23 24// array_walk_recursive を適用する多次元配列を準備します。 25$data = [ 26 'products' => [ 27 'fruits' => [ 28 'apple', 29 'banana', 30 'orange' 31 ], 32 'vegetables' => [ 33 'carrot', 34 'potato' => 'small potato', 35 'leafy_greens' => [ 36 'spinach', 37 'kale' 38 ] 39 ] 40 ], 41 'settings' => [ 42 'version' => '1.0', // 文字列 43 'debug_mode' => true // 文字列ではないので変更されない 44 ] 45]; 46 47echo "--- 処理前の配列の状態 ---\n"; 48print_r($data); 49 50// array_walk_recursive を実行し、その戻り値 (bool) を取得します。 51// array_walk_recursive は、処理が成功した場合は true、失敗した場合は false を返します。 52// 第一引数の $data は参照渡しなので、関数内で変更された値が元の $data に反映されます。 53$is_successful = array_walk_recursive($data, 'convertValueToUppercase'); 54 55echo "\n--- array_walk_recursive の処理結果 ---\n"; 56 57if ($is_successful) { 58 echo "array_walk_recursive は正常に実行されました。\n"; 59 echo "\n--- 処理後の配列の状態 ---\n"; 60 print_r($data); 61} else { 62 echo "array_walk_recursive は何らかの理由で失敗しました。\n"; 63 // 失敗するケースの例: コールバック関数が見つからない、 64 // または第一引数に配列以外のものが渡された場合など。 65} 66 67?>
array_walk_recursiveはPHP 8の組み込み関数で、多次元配列の全ての要素を再帰的に巡回し、ユーザー定義のコールバック関数を適用します。
第一引数&$arrayには処理対象の配列を指定します。この引数は参照渡しのため、コールバック関数内で要素の値を直接変更すると、元の配列にも変更が反映されます。第二引数$callbackには、配列の各要素に適用したい処理を記述した関数名を指定します。このコールバック関数は、現在の要素の値(参照渡し)とキーを引数として受け取ります。オプションの第三引数$argを使用すると、コールバック関数に追加のデータを渡すことが可能です。
この関数は処理が成功した場合はブール値のtrueを、何らかの理由で失敗した場合はfalseを返します。
サンプルコードでは、多次元配列の文字列要素を大文字に変換する例を示しています。array_walk_recursiveを実行することで、元の配列$data内の全ての文字列要素が「convertValueToUppercase」関数によって大文字に変換され、その処理の成否が変数$is_successfulに格納されます。これにより、多次元配列を効率的に操作し、処理の成否を確認できます。
array_walk_recursive は、多次元配列を含むすべての要素に対してコールバック関数を再帰的に適用します。第一引数の配列と、コールバック関数の第一引数である値は参照渡しです。これにより、コールバック関数内で要素を変更すると元の配列にも変更が反映されますので、意図しない変更に注意が必要です。関数の戻り値は処理の成否を示す真偽値 (true/false) です。これにより、関数が正常に実行されたかを確認し、エラー発生時の対応を行えます。多次元配列の場合、すべての階層の要素が再帰的に処理されます。コールバック関数内で is_string() のように要素の型をチェックすることで、特定の型の要素のみを安全に処理できます。