PHP原始碼閱讀 count函式

2022-01-11 01:35:23 字數 2711 閱讀 1585

在php程式設計中,在遍歷陣列的時候經常需要先計算陣列的長度作為迴圈結束的判斷條件,而在php裡面對陣列的操作是很頻繁的,因此count也算是乙個常用函式,下面研究一下count函式的具體實現。

我在github上有對php原始碼更詳細的註解。感興趣的可以圍觀一下,給個star。php5.4原始碼註解。可以通過commit記錄檢視已新增的註解。

int count ( mixed

$array_or_countable [, int $mode = count_normal ] )

count函式計算陣列或者物件裡面的所有元素個數。

對於物件來說,如果你安裝了spl擴充套件,可以通過實現countable介面來呼叫count函式。countable介面有且僅有乙個方法countable::count(),該方法的返回count()函式的返回值。

mode

如果引數mode設為count_recursive(或1),count()會遞迴地計算該陣列。在計算多維陣列的時候特別有用。

如果第乙個引數不是陣列或者實現countable介面的物件,count函式將返回1。

注意:count函式可以檢測遞迴避免無限迴圈,但會在遇到無限遞迴或得到比期望值大的時候返回e_warning提示。

$arr1 = array(1, 2, 3, 4, 5);

$val1 = count($arr1); //

5

$val2_1 = count($arr2); //

4$val2_2 = count($arr2, 1); //

6

$str = "hello world";

$int_val = 1;

$val3 = count($str); //

1$val4 = count($int_val); //

1

class

user

$user = new

user();

$val5 = count($user); //

1$val6 = count((array) $user); //

2

class user extends

arrayobject

public

function

getname()

public

function

count

() }

$user2 = new

user();

$val7 = count($user2); //

2

class user implements

countable

}$user3 = new

user();

$val8 = count($user3); //

3

進入switch語句檢測引數型別

如果是null,直接返回0

如果是陣列,呼叫php_count_recursive函式機選陣列元素個數

如果是物件,先檢查是否為陣列物件(array-like object),如果是,則計算陣列物件的數量

否則,如果物件實現了countable介面,則呼叫countable的count方法

最後,其他型別比如整型陣列或字串,都返回1。

如果是普通陣列,count函式會呼叫php_count_recursive函式實現其功能的執行步驟如下:

如果當前hash bucket被遞迴訪問的次數大於1,說明重複遞迴,染回e_warning錯誤

否則計算當前陣列層數的陣列元素個數

如果有遞迴引數選項,則繼續遞迴訪問

如果引數是物件型別,實現時會先判斷handler是否被定義。而handler是php核心中物件的結構體,其中包含有count_elements字段,實際上是乙個函式。如果某個物件表現得想陣列一樣,即通常說的array-like object,那麼就會執行count_elements函式。具體實現是類繼承php的arrayobject,並在類裡面實現count函式,具體呼叫的就是count函式,如果類沒有實現count函式,則count返回0,否則返回物件的count函式的返回值。

如果是其他的資料型別

1、字串

2、數字

3、物件分支中兩個if判斷都為false的情況,即沒有繼承arrayobject且沒有實現countable介面。

這些型別通通返回1。

需要注意的是,如果需要計算的是物件的屬性數量,可以先將物件轉換成陣列,然後呼叫count函式。如:

$count_value = count((array) $user);

閱讀count函式的原始碼過程中,在其中一步卡住了,就是if (z_obj_ht_p(array)->count_elements)這一步,因為始終無法寫出進入這個分支的demo,在網上搜尋了很多資料也未果,因此請教了tipi的reeze,最終得到了想要的答案。不懂就要問,哈哈。

原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。

最後再安利一下,我在github有對php原始碼更詳細的註解。感興趣的可以圍觀一下,給個star。php5.4原始碼註解。可以通過commit記錄檢視已新增的註解。

PHP原始碼閱讀 number format函式

上次講到php是如何解析大整數的,一筆帶過了number format的處理,再詳細閱讀該函式的原始碼,以下是小分析。string number format float number int decimals 0 string number format float number int deci...

PHP原始碼閱讀 number format函式

上次講到php是如何解析大整數的,一筆帶過了number format的處理,再詳細閱讀該函式的原始碼,以下是小分析。string number format float number int decimals 0 string number format float number int deci...

《原始碼閱讀》原始碼閱讀技巧,原始碼閱讀工具

檢視某個類的完整繼承關係 選中類的名稱,然後按f4 quick type hierarchy quick type hierarchy可以顯示出類的繼承結構,包括它的父類和子類 supertype hierarchy supertype hierarchy可以顯示出類的繼承和實現結構,包括它的父類和...