array_walk() 是 PHP 遍歷並**原地修改**數組的核心函數,支援傳遞用戶數據、遞歸處理多維數組。本文詳細講解語法、參數陷阱、常見模式與性能對比。
array_walk(array &$array, callable $callback, mixed $arg = null): bool
fn(&$value, $key, $arg) { ... },第一參數必須按引用 &$value 才能修改原數組。true,失敗拋警告。$fruits = ['apple', 'banana', 'orange'];
array_walk($fruits, function(&$item, $key, $prefix) {
$item = $prefix . $item;
}, 'Fruit: ');
print_r($fruits);
/*
Array
(
[0] => Fruit: apple
[1] => Fruit: banana
[2] => Fruit: orange
)
*/
function walkRecursive(array &$array, callable $callback, $arg = null) {
array_walk($array, function(&$value, $key) use (&$walkRecursive, $callback, $arg) {
if (is_array($value)) {
$walkRecursive($value, $callback, $arg);
} else {
$callback($value, $key, $arg);
}
});
}
$data = [
'user' => ['name' => 'Alice', 'tags' => ['php', 'laravel']],
'settings' => ['theme' => 'dark', 'lang' => 'en']
];
walkRecursive($data, function(&$v, $k) {
if (is_string($v)) $v = strtoupper($v);
});
print_r($data);
// 所有字符串值變大寫,鍵名不變
| 錯誤代碼 | 問題 | 正確寫法 |
|---|---|---|
array_walk($arr, fn($v) => $v = strtoupper($v)); | $v 非引用,修改無效 | fn(&$v) => $v = strtoupper($v) |
array_walk($arr, 'strtoupper'); | strtoupper 不接受引用參數,報警告 | 用 array_map('strtoupper', $arr) 返回新數組 |
回調中 unset($value) | 僅銷毀局部變量,原數組元素不變 | 回調返回 false 可停止遍歷,需刪除用 array_walk 配合 unset($array[$key]) 在外部 |
| 修改鍵名 | array_walk 無法修改鍵名 | 用 array_combine(array_map(...), $arr) 或 foreach 重建 |
| 特性 | array_walk | array_map | foreach |
|---|---|---|---|
| 修改原數組 | ✅ (引用) | ❌ (返回新) | ✅ |
| 返回值 | bool | 新數組 | 無 |
| 多數組並行遍歷 | ❌ | ✅ | 手動實現 |
| 傳遞額外參數 | ✅ ($arg) | ❌ (用 use/箭頭函數) | 直接用外部變量 |
| 可中斷遍歷 | 回調返回 false | ❌ | break |
| 性能 | 略快於 foreach | 中等 | 最快(無函數調用開銷) |
function sanitizeArray(array &$data, array $rules) {
array_walk($data, function(&$value, $key) use ($rules) {
if (isset($rules[$key])) {
$rule = $rules[$key];
// 修剪
if ($rule['trim'] ?? false) $value = trim($value);
// 類型轉換
if (isset($rule['type'])) {
settype($value, $rule['type']);
}
// 回調處理
if (isset($rule['callback']) && is_callable($rule['callback'])) {
$value = $rule['callback']($value);
}
}
});
}
$input = [' name ' => ' Alice ', 'age' => '25', 'email' => 'ALICE@EXAMPLE.COM'];
sanitizeArray($input, [
'name' => ['trim' => true],
'age' => ['type' => 'integer'],
'email' => ['trim' => true, 'callback' => 'strtolower'],
]);
print_r($input);
// ['name'=>'Alice', 'age'=>25, 'email'=>'alice@example.com']
array_walk。array_map。foreach。掌握 array_walk 的引用機制與遞歸模式,能優雅處理多維數組清洗、標準化、批量轉換等高頻任務。