這篇文章為大家帶來了關於PHP的相關知識,其中主要跟大家介紹數組是怎麼靈活支持多數據類型的,感興趣的朋友下面一起來看一下吧,希望對大家有幫助。
在PHP中,陣列資料結構的應用處理是使用頻率非常高的,相對於Java、C 這種強型別語言來說,PHP的陣列簡直可以說是太好用了,可以儲存各種類型的資料(如:數字、字串甚至物件等),為開發帶來了極大的便利。
基於 PHP 陣列的強大特性,我們可以輕易地實作更複雜的資料結構,例如堆疊、佇列、列表、集合、字典等。
你是否迫不及待的想要一探究竟:PHP到底是如何實現陣列的呢?
PHP 陣列其內部是使用 HashTable 結構來實現的,那就先來簡單說說HashTable吧!
HashTable又稱散列表,是透過key-value的方式來有效率地存取資料的一種結構。哈希表是數組和鍊錶的一種合併,整合了數組的尋址快,鍊錶的插入快的特徵於一身。
HashTable主要分為兩個環節:
1. 雜湊函數:雜湊函數將要尋找的值轉換成數字索引,透過數字索引可以快速的找到值存在的位置。
2. 雜湊碰撞:理想情況下,不同的值通過雜湊函數後,出來的結果是不一樣的;如果不一樣的值,雜湊後出來一樣的數字,我們稱之為哈希碰撞。
因此應用 HashTable 就必須要面臨解決雜湊碰撞的問題,主要的解法有兩種:鍊錶法,開放尋址法。
在zend_type.h檔中,可以找到HashTable 的主要結構定義如下:
zend_陣列型別
##挑選幾個重點成員介紹一下:Bucket 類型
Bucket 的結構比較簡單,主要用來保存元素的key和value,以及一個整數的h(雜湊值,或叫做雜湊值)。$data = array( 'hello' => 'haha', 1 => 'me to' 'world' => 'world', 2 => 2 ); unset($data[1]);那上面的hash結構應該是什麼樣的呢? arData儲存的結果應該是什麼樣子呢? 畫個圖例來看看吧,更直觀一些: #arData是Bucket類型的指針,用來具體儲存每個元素的key, value,依照插入元素的順序儲存資料的,所以陣列的順序也是靠這個來保證。 每個arData數組的元素,從圖中可以看到,左邊負數是哈希值取模後的值,存儲的是右邊arData的索引;如-8衝突了,則存儲了鍊錶的頭元素。
arData[0]: key='hello',h=xx(具體某個值),val = 'haha'arData[1]: val是type= IS_UNDEF 的zval(被unset後,不是立即被刪除,而是置成IS_UNDEF)arData[2]: key='world',h=xx(具體某個值),val = 'world '##上面的範例很具體地解釋了nNumUsed,nNumOfElements,arData的意義。 3、PHP 陣列的有序性陣列中各元素的順序和插入順序一致,這個是怎麼實現的呢? 為了實現PHP 數組的有序性,PHP 底層的散列表在散列函數與元素數組之間加了一層映射表,這個映射表也是一個數組,大小和存儲元素的數組相同,儲存元素的類型為整數,用於保存元素在實際儲存的有序數組中的下標—— 元素按照先後順序依序插入實際儲存數組,然後將其數組下標按照雜湊函數散列出來的位置儲存在新加的映射表中: 這樣,就可以完成最終儲存資料的有序性了。 PHP 數組底層結構中並沒有明確標識這個中間映射表,而是與arData 放到了一起,在數組初始化的時候並不僅僅分配用於存儲Bucket 的內存,還會分配相同數量的uint32_t 大小的空間,這兩塊空間是一起分配的,然後將arData 偏移到儲存元素數組的位置,而這個中間映射表就可以透過arData 向前存取。 總結PHP中的陣列其特點就是將 values 對應到 keys 的型別。與其他語言不同的是,PHP中陣列的 key 可以是字串,而values可以是任意型別。 除常規增刪改查之外,陣列還有很多其他操作,例如複製、合併、銷毀、重置等,這些操作對應的程式碼都位於zend_hash.c 中,有興趣的同學可以去了解一下。 推薦學習:《arData[3]: key=NULL,h=2(可能會雜湊值衝突),val = 2
….
PHP影片教學》
以上是深析PHP數組是怎麼靈活支援多資料類型的詳細內容。更多資訊請關注PHP中文網其他相關文章!