PHP原始碼閱讀:array_push 和 array_unshift 函式

hoohack發表於2016-06-07
在PHP中,在陣列中新增元素也是一種很常用的操作,分別有在陣列尾部和頭部新增元素,看看PHP內部是如何實現陣列插入的操作。

array_push

array_push函式將array引數看做一個棧,將傳遞進來的變數壓倒array的尾部。array的長度隨著被壓進去的變數個數增加。下面的程式碼有意義的效果:

如果只需要新增一個元素到陣列,使用$array[] 這種方式更好,因為這樣做不用呼叫函式。

執行示例

執行步驟

array_push函式相對比較簡單,就相當於壓棧操作,把array看做一個棧,然後對每一個引數,讓其變成引用,引用數加一,然後新增它到陣列的尾部。

內部實現的流程圖如下:

array_push流程圖

原始碼解讀

新增元素使用了zend_hash_next_index_insert函式,此函式是_zend_hash_next_index_insert函式的巨集定義,這個函式是PHP內部實現陣列的資料結構–雜湊表包含的一些API,這個API用於追加元素到雜湊表或者更新雜湊表中已有的雜湊值。此函式實現的流程圖如下:

zend_insert

array_unshift

array_unshift函式將資料元素插入到陣列的頭部,插入時是作為整體插入,因此後面的引數將保持同樣的順序。插入後所有的數值鍵名將修改為從零開始計數,所有的文字鍵名不變。

執行示例

執行步驟

1、呼叫php_splice將資料元素插入到陣列頭部,用新的雜湊表替換就得雜湊表並將其銷燬

2、如果操作後的stack等於執行時的符號表,則重置雜湊表的內部指標

3、stack指向新的雜湊表,釋放新的雜湊表紅箭,銷燬就得雜湊表

原始碼解讀

由上面的步驟可知,array_unshift的核心步驟是php_splice函式。對於array_unshift函式,php_splice實現時新建一個雜湊表out_hash,將需要插入的list資料先插入到out_hash中,然後再把原來的陣列資料寫入到out_hash中,這樣實現在陣列前面插入資料元素的功能。

實現的效果圖如下:

php_splice

小結

要理解array_push函式的執行過程主要理解棧的思想即可,而array_unshift則是新建一個陣列,然後將兩陣列合併為結果陣列。 這次閱讀原始碼過程中,同時也研究了PHP中的雜湊表資料結構及一些API,也給自己補充了一些雜湊表的知識。學習到了PHP底層是使用雙向連結串列做雜湊衝突的處理,獲益匪淺。日後再做關於PHP資料結構的分享。

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

如果本文對你有幫助,點收藏的同時也請點下推薦吧,謝謝^_^

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

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

PHP原始碼閱讀:array_push 和 array_unshift 函式 PHP原始碼閱讀:array_push 和 array_unshift 函式

相關文章