PHP 5.5 引入 array_column(),極大簡化了「從多維陣列中提取單一欄位組成新陣列」的常見操作。本文詳細解析其語法、參數、返回值行為,並提供豐富實戰範例,同時附上 PHP 5.4 及以下版本的 Polyfill 實現。
array_column(array $input, mixed $column_key, mixed $index_key = null): array
$input:輸入多維陣列(或實作 Traversable 的物件)$column_key:要提取的欄位鍵名(字串)或數字索引(整數)$index_key(可選):結果陣列的索引鍵,可為字串鍵名或數字索引;預設為 0 起始數字索引$records = [
['id' => 2135, 'first_name' => 'John', 'last_name' => 'Doe'],
['id' => 3245, 'first_name' => 'Sally', 'last_name' => 'Smith'],
['id' => 5342, 'first_name' => 'Jane', 'last_name' => 'Jones'],
['id' => 5623, 'first_name' => 'Peter', 'last_name' => 'Doe'],
];
$firstNames = array_column($records, 'first_name');
print_r($firstNames);
/*
Array
(
[0] => John
[1] => Sally
[2] => Jane
[3] => Peter
)
*/
$records = [
[1, 'John', 'Doe'],
[2, 'Sally', 'Smith'],
[3, 'Jane', 'Jones'],
];
$lastNames = array_column($records, 2); // 數字索引 2 對應第三欄
print_r($lastNames);
/*
Array
(
[0] => Doe
[1] => Smith
[2] => Jones
)
*/
$mismatchedColumns = [
['a' => 'foo', 'b' => 'bar', 'e' => 'baz'],
['a' => 'qux', 'c' => 'quux', 'd' => 'corge'],
['a' => 'grault','b' => 'garply','e' => 'waldo'],
];
$foo = array_column($mismatchedColumns, 'a', 'b');
print_r($foo);
/*
Array
(
[bar] => foo // 存在 b 鍵
[0] => qux // 第二行無 b 鍵,退回數字索引 0
[garply] => grault // 存在 b 鍵
)
*/
注意:$index_key 對應值缺失時,該行在結果中以 0 為鍵(後續相同情況會覆蓋);重複值會導致後者覆蓋前者。
若專案仍運行於 PHP 5.3/5.4,可引入以下實現:
if (!function_exists('array_column')) {
function array_column($input, $columnKey, $indexKey = null) {
$columnKeyIsNumber = is_numeric($columnKey);
$indexKeyIsNull = is_null($indexKey);
$indexKeyIsNumber = is_numeric($indexKey);
$result = [];
foreach ((array)$input as $key => $row) {
// 取值
if ($columnKeyIsNumber) {
$tmp = array_slice($row, $columnKey, 1);
$tmp = (is_array($tmp) && !empty($tmp)) ? current($tmp) : null;
} else {
$tmp = isset($row[$columnKey]) ? $row[$columnKey] : null;
}
// 確定結果鍵名
if (!$indexKeyIsNull) {
if ($indexKeyIsNumber) {
$key = array_slice($row, $indexKey, 1);
$key = (is_array($key) && !empty($key)) ? current($key) : null;
$key = is_null($key) ? 0 : $key;
} else {
$key = isset($row[$indexKey]) ? $row[$indexKey] : 0;
}
}
$result[$key] = $tmp;
}
return $result;
}
}
| 方案 | PHP 版本 | 可讀性 | 執行速度 | 記憶體 |
|---|---|---|---|---|
array_column() | ≥ 5.5 | ★★★★★ | 最快(C 實現) | 低 |
array_map(function($r){return $r['col'];}, $arr) | ≥ 5.3 | ★★★★☆ | 中等 | 中 |
foreach 迴圈手動構建 | 所有 | ★★★☆☆ | 最慢 | 高 |
$index_key 時,相同鍵值的後者覆蓋前者,無報警。user.profile.name 這類路徑,需自行遞歸或配合 array_map。array_column() 是 PHP 陣列處理工具箱中的「瑞士軍刀」,善用它能讓資料轉換代碼更簡潔、更易維護。升級至 PHP 5.5+ 後請優先採用原生函數;舊版本環境請引入上方 Polyfill 以保持 API 一致性。