[PHP源碼閱讀]count函數,php源碼count函數_PHP教程

來源:互聯網
上載者:User

[PHP源碼閱讀]count函數,php源碼count函數


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

我在github上有對PHP源碼更詳細的註解。感興趣的可以圍觀一下,給個star。PHP5.4源碼註解。可以通過commit記錄查看已添加的註解。

count

int count ( mixed $array_or_countable [, int $mode = COUNT_NORMAL ] )

countFunction Compute數組或者對象裡面的所有元素個數。

對於對象來說,如果你安裝了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

多維陣列

$arr2 = array('apple', 'banana', array('cat', 'camel'), 'dog');$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 {    private $name;    private $address;}$user = new User();$val5 = count($user); // 1$val6 = count((array) $user); // 2

array-like對象

    class User extends ArrayObject {        private $name;        public function __construct() {            $this->name = 'hhq';        }        public function getName() {            return $this->name;        }        public function count() {            return 2;        }    }    $user2 = new User();    $val7 = count($user2); // 2

實現Countable介面對象

    class User implements Countable {        public function count() {            return 3;        }    }    $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記錄查看已添加的註解。

更多源碼文章,歡迎訪問個人首頁繼續查看:hoohack

http://www.bkjia.com/PHPjc/1130480.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1130480.htmlTechArticle[PHP源碼閱讀]count函數,php源碼count函數 在PHP編程中,在遍曆數組的時候經常需要先計算數組的長度作為迴圈結束的判斷條件,而在PHP裡面對...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.