首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP count() 函數完全指南:陣列長度計算、陷阱與現代替代方案

     編輯:PHP 相關知識

前言

count() 是 PHP 計算陣列元素個數、物件可數屬性、或標量值「單元數」的核心函數。看似簡單,實則隱藏多個新手易踩的坑。本文將徹底解析其行為、參數模式、常見誤區與現代最佳實踐。

函數原型

count(Countable|array $value, int $mode = COUNT_NORMAL): int
  • COUNT_NORMAL(預設,0):不遞迴計算多維陣列。
  • COUNT_RECURSIVE(1):遞迴計算多維陣列所有元素總數。

核心行為對照表

輸入類型輸入範例返回值說明
索引陣列[1,2,3]3正常計算
關聯陣列['a'=>1,'b'=>2]2正常計算
空陣列[]0正常
未初始化變數$undef0不報錯,返回 0(易誤判)
nullnull0特例
標量(int/float/string/bool)123 / "abc" / true1視為 1 個單元
物件new stdClass()1預設 1;實作 Countable 則呼叫 count()
資源fopen(...)1視為 1 個單元

三大經典陷阱

陷阱一:未初始化變數返回 0,與空陣列無法區分

<?php
// 未定義 $arr
if (count($arr) > 0) { ... } // 不會進入,但也沒有警告(PHP 8.0+ 可能有 deprecation)

// 正確做法:先檢查是否存在
if (isset($arr) && count($arr) > 0) { ... }
// 或 PHP 7.0+ 
if (($arr ?? []) !== []) { ... }
// 或直接用 empty() 反向邏輯(注意 empty('0') 為 true)
if (!empty($arr)) { ... }

陷阱二:COUNT_RECURSIVE 計算方式易誤解

<?php
$arr = [
    'a' => [1, 2],
    'b' => [3, 4, 5]
];

echo count($arr);              // 2 (頂層元素)
echo count($arr, COUNT_RECURSIVE); // 7 = 2(頂層鍵) + 2 + 3 (子元素)
// 並非單純「所有葉子節點總和」,會包含每層鍵的計數

陷阱三:Countable 介面實作錯誤導致無限遞迴

<?php
class BadCollection implements Countable {
    private $items = [];
    public function count(): int {
        return count($this->items); // 正確:委託內部陣列
    }
}

class EvilCollection implements Countable {
    public function count(): int {
        return count($this); // 錯誤!觸發 __invoke 或無限遞迴(PHP 7.2+ 會拋錯)
    }
}

現代最佳實踐(PHP 7.4+)

1. 判斷「非空陣列」首選 !empty() 或 ?? []

$items = $data['items'] ?? [];
if ($items) { ... } // 空陣列為 false,非空為 true

2. 物件集合實作 Countable + IteratorAggregate

<?php
class UserCollection implements Countable, IteratorAggregate {
    private array $users = [];
    
    public function add(User $user): self { $this->users[] = $user; return $this; }
    
    public function count(): int { return count($this->users); }
    
    public function getIterator(): Traversable { return new ArrayIterator($this->users); }
}

$col = new UserCollection();
$col->add(new User())->add(new User());
echo count($col); // 2
foreach ($col as $user) { ... } // 可直接遍歷

3. 避免在循環條件中重複呼叫 count()

<?php
// 慢
for ($i = 0; $i < count($bigArray); $i++) { ... }

// 快
$len = count($bigArray);
for ($i = 0; $i < $len; $i++) { ... }

// 更現代:foreach
foreach ($bigArray as $item) { ... }

4. 多維陣列總葉子數計算(遞迴或扁平化)

<?php
function countLeaves(array $arr): int {
    $count = 0;
    array_walk_recursive($arr, function() use (&$count) { $count++; });
    return $count;
}
// 或
$count = count(array_merge(...array_values($arr))); // 仅限二维数组

效能對比

總結

  1. count() 對陣列為 O(1),極快,放心使用。
  2. 未定義變數返回 0 不報錯,務必配合 isset() 或 ?? [] 使用。
  3. 標量/物件/資源均返回 1,非陣列語境下極易誤判,嚴格檢查 is_array()。
  4. 現代代碼優先用 foreach、!empty()、?? [] 替代直接 count() 判斷。
  5. 自定集合類實作 Countable 即可原生支援 count()。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
操作時間複雜度備註
count($arr)O(1)PHP 內部維護元素計數器
count($arr, COUNT_RECURSIVE)O(n)需遞迴遍歷
sizeof($arr)O(1)count 別名,建議統一用 count