陣列是 PHP 最強大、最常用的資料結構,同時扮演列表、映射、集合、堆疊、佇列等角色。本文系統整理陣列定義方式、索引/關聯/多維分類、核心操作與現代最佳實踐。
int 或 string,值為任意型別,保持插入順序。0, 1, 2...(列表語意)。[](PHP 5.4+,推薦)$indexed = [1, 'zhangsan', 10, 'nan'];
$assoc = ['id'=>1, 'name'=>'zhangsan', 'age'=>10, 'sex'=>'nan'];
$mixed = [0 => 'a', 'key' => 'b', 5 => 'c']; // 避免
array() 傳統語法$indexed = array(1, 'zhangsan', 10, 'nan');
$assoc = array('id'=>1, 'name'=>'zhangsan', 'age'=>10, 'sex'=>'nan');
$user = [];
$user[] = 1; // 自動索引 0
$user[] = 'zhangsan';
$user['id'] = 100; // 指定字串鍵
$user[5] = 'gap'; // 下一個自動索引為 6
$users = [
['id'=>1, 'name'=>'zhangsan', 'age'=>10, 'sex'=>'nan'],
['id'=>2, 'name'=>'lisi', 'age'=>20, 'sex'=>'nv'],
['id'=>3, 'name'=>'wangwu', 'age'=>30, 'sex'=>'nan'],
];
// 存取
echo $users[1]['name']; // lisi
echo $users[2]['age']; // 30
$database = [
'user' => [
['id'=>1, 'name'=>'zhangsan', 'age'=>10, 'sex'=>'nan'],
['id'=>2, 'name'=>'lisi', 'age'=>20, 'sex'=>'nv'],
],
'score' => [
['user_id'=>1, 'chinese'=>90, 'math'=>80, 'english'=>70],
['user_id'=>2, 'chinese'=>60, 'math'=>40, 'english'=>70],
],
'contact' => [
['user_id'=>1, 'phone'=>'110', 'email'=>'aaa@bbb.com'],
['user_id'=>2, 'phone'=>'120', 'email'=>'bbb@ccc.com'],
],
];
echo $database['score'][1]['chinese']; // 60
| 操作 | 函數/語法 | 備註 |
|---|---|---|
| 新增元素 | $arr[] = $val / array_push() | 索引自動遞增 |
| 指定鍵新增/修改 | $arr['key'] = $val | 覆蓋既有鍵 |
| 刪除元素 | unset($arr['key']) | 不重新索引 |
| 刪除並重新索引 | array_splice($arr, $offset, $len) | 類似 JS splice |
| 合併陣列 | array_merge($a, $b) | 字串鍵後者覆蓋,數字鍵重新索引 |
| 遞迴合併 | array_merge_recursive() | 相同字串鍵合併為陣列 |
| 去重 | array_unique($arr) | 保留首次出現,保持鍵 |
| 翻轉鍵值 | array_flip($arr) | 值必須為 int/string |
| 取得所有鍵 | array_keys($arr) | |
| 取得所有值 | array_values($arr) | 重新索引 0... |
| 搜尋值對應鍵 | array_search($val, $arr, true) | 第三參數 true 嚴格比較 |
| 檢查鍵存在 | array_key_exists('key', $arr) / isset($arr['key']) | isset 若值為 null 回傳 false |
| 檢查值存在 | in_array($val, $arr, true) | 嚴格模式建議開啟 |
current(), key(), next(), prev(), reset(), end(), each()(已棄用)。
現代寫法:foreach ($arr as $k => $v)、array_keys()、array_values()。
function csvToArray(string $path): array {
$rows = [];
if (($handle = fopen($path, 'r')) !== false) {
$headers = fgetcsv($handle);
while (($row = fgetcsv($handle)) !== false) {
$rows[] = array_combine($headers, $row);
}
fclose($handle);
}
return $rows;
}
$users = csvToArray('users.csv');
// [['id'=>'1','name'=>'Alice',...], ...]
| 場景 | 建議 |
|---|---|
| 百萬級元素 | 用 Generator 逐行處理,避免一次載入 |
頻繁 in_array 查詢 | 改用 array_flip 後 isset($flipped[$val]) O(1) |
大量 array_push | $arr[] = $val 語法更快 |
| 固定結構大量資料 | 考慮 SplFixedArray 節省記憶體 |
| 錯誤程式碼 | 問題 | 修正 |
|---|---|---|
$arr = [1,2]; echo $arr[2]; | 索引越界 | isset($arr[2]) 先檢查 |
unset($arr); echo $arr[0]; | 銷毀整個陣列 | unset($arr[0]) 刪除單元素 |
array_merge([1,2], [3,4]) 鍵重置 | 數字鍵重新索引 | 需保留鍵用 + 運算子:[0=>1] + [2=>3] |
in_array('0', [false]) 為 true | 鬆散比較 | in_array('0', [false], true) |
$arr = [1,2]; foreach($arr as &$v) {} foreach($arr as $v) {} | 參考殘留汙染 | 首輪 unset($v) 或改用索引賦值 |
總結:陣列是 PHP 的瑞士刀。掌握 [] 短語法、索引/關聯語意區分、多維巢狀結構、核心增刪改查函數、foreach 遍歷與參考陷阱,即能駕馭 90% 以上的資料處理場景。大規模資料請善用 Generator、SplFixedArray 或資料庫游標。