count() 是 PHP 統計陣列元素個數的核心函數,但其第二個參數 $mode 常被忽略,導致多維陣列統計結果與預期不符。本文透過實測案例,徹底釐清 COUNT_NORMAL (0) 與 COUNT_RECURSIVE (1) 的差異,並提供「取得第一維長度」的標準寫法。
$arr = [
[10, 15, 30],
[10, 15, 30],
[10, 15, 30]
];
echo count($arr, 0); // COUNT_NORMAL = 3 (僅統計第一維:3 個子陣列)
echo count($arr, 1); // COUNT_RECURSIVE = 12 (遞迴統計:3 + 3×3 = 12)
計算邏輯:
COUNT_RECURSIVE = 第一維元素數 (3) + 所有子陣列元素總和 (9) = 12。
$fruits[0][0] = 1;
$fruits[0][3] = 1;
$fruits[0][4] = 1;
echo count($fruits[0]); // 輸出 3 (實際只有 3 個元素,鍵 0,3,4)
PHP 陣列本質是有序映射,**鍵名不連續不影響 count()**,它統計的是實際存在的元素數,而非最大索引+1。
$news = [
['title' => '新聞1', 'view' => 123],
['title' => '新聞2', 'view' => 99],
];
// ❌ 錯誤:不同 PHP 版本/配置下 count($news) 可能回傳 2 或 8
// ✅ 正確:明確指定 COUNT_NORMAL
$rowCount = count($news, COUNT_NORMAL); // 穩定回傳 2
// 判斷是否有資料
if (is_array($news) && count($news, COUNT_NORMAL) > 0) {
// 有資料
}
count($arr) 預設 COUNT_NORMAL,行為一致。TypeError,**務必先 is_array() 或 is_countable() 守衛**。| 需求 | 代碼 | 說明 |
|---|---|---|
| 第一維長度(行數) | count($arr, COUNT_NORMAL) | 最常用,明確語義 |
| 所有層級元素總數 | count($arr, COUNT_RECURSIVE) | 含巢狀陣列所有標量值 |
| 特定子陣列長度 | count($arr[0], COUNT_NORMAL) | 如統計第一行欄位數 |
| 安全檢查後再統計 | is_countable($arr) ? count($arr, COUNT_NORMAL) : 0 | PHP 8+ 必備 |
function count_recursive_custom(array $arr, callable $filter = null): int {
$count = 0;
foreach ($arr as $k => $v) {
if ($filter && !$filter($k, $v)) continue;
$count++;
if (is_array($v)) {
$count += count_recursive_custom($v, $filter);
}
}
return $count;
}
// 使用:統計所有非 null 葉子節點
$total = count_recursive_custom($data, fn($k, $v) => !is_null($v));
count($arr, COUNT_NORMAL) 穩定獲取第一維長度,COUNT_RECURSIVE 統計全樹節點。**PHP 8+ 強制型別檢查,務必加 is_countable() 守衛**。理解陣列本質為有序映射,鍵名稀疏不影響計數,避免「最大索引+1」誤區。