array_walk() 是 PHP 陣列操作的利器,能對陣列每個元素執行使用者自訂函式,支援傳址修改原陣列值、傳遞額外參數、以及類別方法作為回調。本文透過多個實例全方位示範其用法。
基本語法
bool array_walk ( array &$array , callable $callback [, mixed $userdata = NULL ] )
&$array:傳址,回調可修改原陣列
$callback($value, $key, $userdata):回調函式簽名
$userdata:額外參數,如前綴字串、配置物件等
範例 1:輸出陣列鍵值對(含額外參數)
$fruits = ['a' => 'apple', 'b' => 'banana', 'c' => 'cherry'];
function print_fruit($value, $key, $prefix) {
echo "{$prefix}: {$key} => {$value}<br>\n";
}
array_walk($fruits, 'print_fruit', '水果清單');
// 輸出:
// 水果清單: a => apple
// 水果清單: b => banana
// 水果清單: c => cherry
範例 2:修改陣列值(首字大寫 + 鍵名大寫)
function capitalize_fruit(&$value, $key) {
$value = ucfirst($value); // 值首字大寫
// 注意:$key 是值傳遞,無法修改原陣列鍵名
// 若需修改鍵名,請用 array_walk + array_combine 或 foreach
}
array_walk($fruits, 'capitalize_fruit');
print_r($fruits);
// Array ( [a] => Apple [b] => Banana [c] => Cherry )
範例 3:類別方法作為回調
class FruitProcessor {
public $prefix = '[處理後] ';
public function process(&$value, $key) {
$this->prefix .= $key . ': ';
$value = strtoupper($value); // 全大寫
}
}
$processor = new FruitProcessor();
// 類別方法回調語法:[$object, 'methodName']
array_walk($fruits, [$processor, 'process']);
print_r($fruits);
// Array ( [a] => [處理後] a: APPLE ... )
範例 4:靜態方法與匿名函式
// 靜態方法
class Util {
public static function dump($v, $k) { var_dump($k, $v); }
}
array_walk($fruits, ['Util', 'dump']);
// 匿名函式(PHP 5.3+)
array_walk($fruits, function(&$v, $k) {
$v = md5($v); // 將值替換為 MD5 雜湊
});
常見陷阱與注意事項
| 陷阱 | 說明 | 正確做法 |
| 修改鍵名 | $key 是值傳遞,修改無效 | 使用 foreach + unset/重建,或 array_combine(array_map(...), $arr) |
| 回調中 break/continue | 無效,array_walk 無法中途跳出 | 改用 foreach 迴圈 |
| 大陣列效能 | 函式呼叫開銷大 | 簡單操作優先用 foreach 或 array_map |
| 內部指標改變 | array_walk 會重置陣列指標 | 不依賴 current()/next() 等指標函式 |
array_walk vs array_map vs foreach
| 特性 | array_walk | array_map | foreach |
| 修改原陣列 | ✓ (傳址) | ✗ (回傳新陣列) | ✓ |
| 回傳值 | bool | 新陣列 | 無 |
| 多陣列並行 | ✗ | ✓ | 手動實作 |
| 可中途跳出 | ✗ | ✗ | ✓ |
| 適用場景 | 原地修改、副作用操作 | 資料轉換、映射 | 通用遍歷、複雜邏輯 |