深入理解PHP之陣列 遍歷順序

2021-09-30 08:54:55 字數 2205 閱讀 5541

)又比如:

<?php

$arr[2

]= 'huixinchen';

$arr[1

]= 2007

;$arr[0

]= 2008

;foreach

($arr

as$key

=>

$val

)要完全了解清楚這個問題, 我想首先應該要大家了解php陣列的內部實現結構………

php的陣列在php中, 陣列是用一種hash結構(hashtable)來實現的, php使用了一些機制, 使得可以在o(1)的時間複雜度下實現陣列的增刪, 並同時支援線性遍歷和隨機訪問.

之前的文章中也討論過,

php的hash演算法

, 基於此, 我們做進一步的延伸.

認識hashtable之前, 首先讓我們看看hashtable的結構定義, 我加了注釋方便大家理解:

typedef

struct

_hashtable

hashtable

;<?php

$arr

= array(1

,2,3

,4,5

,);$arr

= &$arr

;var_export

($arr);

//fatal error: nesting level too deep - recursive dependency?

這個字段就是為了防治迴圈引用導致的無限迴圈而設立的.

檢視上面的結構, 可以看出, 對於hashtable, 關鍵元素就是arbuckets了, 這個是實際儲存的容器, 讓我們來看看它的結構定義:

typedef

struct

bucket

bucket

;我們注意到, 最後乙個元素, 這個是flexible array技巧, 可以節省記憶體,和方便初始化的一種做法, 有興趣的朋友可以google flexible array.

h是元素的hash值,對於數字索引的元素,h為直接索引值(通過nkeylength=0來表示是數字索引).對於數字索引來說, 索引值儲存在arkey中, 索引的長度儲存在nkeylength中.

在bucket中,實際的資料是儲存在pdata指標指向的記憶體塊中,通常這個記憶體塊是系統另外分配的。但有一種情況例外,就是當bucket儲存 的資料是乙個指標時,hashtable將不會另外請求系統分配空間來儲存這個指標,而是直接將該指標儲存到pdataptr中,然後再將pdata指向本結構成員的位址。這樣可以提高效率,減少記憶體碎片。由此我們可以看到php hashtable設計的精妙之處。如果bucket中的資料不是乙個指標,pdataptr為null(本段來自altair的」zend hashtable詳解」)

結合上面的hashtable結構, 我們來說明下hashtable的總結構圖:

深入理解php原理之foreach

), 然後通過每次fe_fetch來遞增pinternalpointer,從而實現順序遍歷.

類似的, 當我們使用, each/next系列函式來遍歷的時候, 也是通過移動陣列的內部指標而實現了順序遍歷, 這裡有乙個問題, 比如:

<?php

$arr

= array(1

,2,3

,4,5

);foreach

($arr

as$v

)while

(list

($key

, $v)=

each

($arr

))?>

huixinchen

2007

2008

所以, 如果你想在數字索引的陣列中按照索引大小遍歷, 那麼你就應該使用for, 而不是foreach

for($i=

0,$l=

count

($arr);

$i<

$l;

$i++

)

深入理解PHP之陣列 遍歷順序

經常會有人問我,php的陣列,如果用foreach來訪問,遍歷的順序是固定的麼?以什麼順序遍歷呢?比如 foreach arr as key val 又比如 arr 2 huixinchen arr 1 2007 arr 0 2008 foreach arr as key val 要完全了解清楚這個...

深入理解PHP之陣列遍歷

經常會有人問我,php的陣列,如果用foreach來訪問,遍歷的順序是固定的麼?以什麼順序遍歷呢?比如 又比如 arr 2 huixinchen arr 1 2007 arr 0 2008 foreach arr as key val 要完全了解清楚這個問題,我想首先應該要大家了解php陣列的內部實...

PHP 陣列遍歷順序理解

比如 又比如 arr 2 huixinchen arr 1 2007 arr 0 2008 foreach arr as key val 要完全了解清楚這個問題,我想首先應該要大家了解php陣列的內部實現結構 在php中,陣列是用一種hash結構 hashtable 來實現的,php使用了一些機制,...