Rumah pembangunan bahagian belakang PHP8 解析PHP8底层内核源码-数组(三)

解析PHP8底层内核源码-数组(三)

Jun 10, 2021 pm 03:00 PM
php8 tatasusunan

本篇文章给大家介绍《解析PHP8底层内核源码-数组(三)》。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

相关文章推荐:《解析PHP8底层内核源码-数组(一)》《解析PHP8底层内核源码-数组(二) 》《解析PHP8底层内核源码-数组(四)

上文已经全文剖析了PHP中数组的基本结构实现和 索引的组成原理

依赖于 _Bucket 和 _zend_array 两个结构体

通过散列函数实现o(1)的复杂度

可是bucket之前还有一个 索引数组  我当时在理解这个索引数组的时候走了不少坑

下图为 $c =array('x'=>1,'y'=>2,'z'=>3,'a'=>0); 中数组c的bucket结构

4a167edc4a1a3e15753be51c8808d70.png

上文已经说了 如果是packed_array的时候 索引数组一直是2 也不会发挥作用

因为如果是packed  key直接是null 也不需要去计算hash值  这个索引数组只是用于快速定位h值所用

224e6328afdb6438b0ae2aa8d7726be.png
$a =array(1,2,3) 的 bucket
typedef struct _Bucket {
zval              val;   //数组的值 ( 复习下 zval只有16个字节)
zend_ulong         h;     // key的 h  值
zend_string      *key;      //当数组为 hash_array时候 会用到 也就是 key的值  
} Bucket;
Salin selepas log masuk

当为packedarray的时候 也不要被val影响了你的学习思路  h值就等于 数组的位置的下标(数组都是从0开始 ,所以下标也从0开始)。比如上文提到的
$b =array(1=>'a',3=>'b',5=>'c');     其中数组b 一样也是packed_array  结构如下

3cd34252d7729f5f230e5a3a5027106.png

因为数组b没有定义第0个数组的值 所以 是无效的   其中$b[1]内容是‘a’ 这里我图上是直接标出了val=a(zval) 其实  是16字节的zval中 类型为 string的 zend_string  这里面又套了之前学到的gc 等 所有PHP内核源码里存在很多无限套娃 方便你温故知新。

返回来再说 $c =array('x'=>1,'y'=>2,'z'=>3,'a'=>0);

结构如下

021be407f0bf388d14f1fb765a32d92.png

这个h值很大  是用key 通过time33计算得来的哈希值 我也不知道为什么叫哈希值 我觉得就是通过time33计算得来的h值  然后形成散列表

0ef5476843285bb71393ffaf965d777.png

散列表主要由两部分组成:存储元素数组、散列函数。一个简单的散列函数可以采用取余数的方式,比如 散列表大小为8 那么在散列表初始化数组的时候就分配8个元素大小的空间,跟进key的hash code 除以8 得到的值就是该元素在数组中的下标。这样就可以通过key映射到存储数组中的具体位置

499a6c30bd075efe1b957822d32e96a.png

但是直接用上面的方式实现数组 会有一个问题 :元素在数组中位置是随机的 它是无序的

PHP中的数组是有序的 所以它在散列函数与元素数组之间加了一层索引表 这个索引表也是一个数组。大小与存储元素的数组相同。但是它存储的元素类型永远都是整型,用于保存元素数组在实际存储的数组中的下标:元素按照先后顺序依次插入实际存储数组中 ,然后将其数组下标按照散列函数计算出的位置存储在新加的索引标中。

5c9f67f91d7a5d3eccb667e16842d7a.png

第一步计算出来 4 然后 取索引表中 找到-4  因为这是第0个数组所以把索引表中第-4个数组里面的值设置为0   然后把真正的数组表中第0个元素设置为真正赋值的zval

散列表中不同元素的key 可能最后计算得到的哈希值 是一样的 也就是指向同一个索引表中的下标 这个时候就会发生hash冲突  。因为索引表只能存一个元素  PHP为了实现hash冲突 采用了拉链法  就是把值用链表拉起来  。可以参考下图 《PHP7 内核剖析-秦朋》

0d97a77d9d7bce4216fca1176b53034.png

正常情况 val.u2.next 的值为-1 也就是初始值 一旦出现hash冲突 那么这里的值就会指向 冲突之前的数组的真实位置 。

▏本文经原作者PHP崔雪峰同意,发布在php中文网,原文地址:https://zhuanlan.zhihu.com/p/360952022

Atas ialah kandungan terperinci 解析PHP8底层内核源码-数组(三). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk mengalih keluar elemen pendua dari tatasusunan PHP menggunakan gelung foreach? Bagaimana untuk mengalih keluar elemen pendua dari tatasusunan PHP menggunakan gelung foreach? Apr 27, 2024 am 11:33 AM

Kaedah menggunakan gelung foreach untuk mengalih keluar elemen pendua daripada tatasusunan PHP adalah seperti berikut: melintasi tatasusunan, dan jika elemen itu sudah wujud dan kedudukan semasa bukan kejadian pertama, padamkannya. Contohnya, jika terdapat rekod pendua dalam hasil pertanyaan pangkalan data, anda boleh menggunakan kaedah ini untuk mengalih keluarnya dan mendapatkan hasil tanpa rekod pendua.

Seni PHP Array Deep Copy: Menggunakan Kaedah Berbeza untuk Mencapai Salinan Sempurna Seni PHP Array Deep Copy: Menggunakan Kaedah Berbeza untuk Mencapai Salinan Sempurna May 01, 2024 pm 12:30 PM

Kaedah untuk tatasusunan penyalinan dalam dalam PHP termasuk: Pengekodan dan penyahkodan JSON menggunakan json_decode dan json_encode. Gunakan peta_tatasusunan dan klon untuk membuat salinan kunci dan nilai yang mendalam. Gunakan bersiri dan menyahsiri untuk bersiri dan menyahsiri.

Pembalikan nilai kunci tatasusunan PHP: analisis perbandingan prestasi kaedah yang berbeza Pembalikan nilai kunci tatasusunan PHP: analisis perbandingan prestasi kaedah yang berbeza May 03, 2024 pm 09:03 PM

Perbandingan prestasi kaedah membalik nilai kunci tatasusunan PHP menunjukkan bahawa fungsi array_flip() berprestasi lebih baik daripada gelung for dalam tatasusunan besar (lebih daripada 1 juta elemen) dan mengambil masa yang lebih singkat. Kaedah gelung untuk membalikkan nilai kunci secara manual mengambil masa yang agak lama.

Amalan Terbaik untuk Menyalin Dalam Tatasusunan PHP: Temui Kaedah Cekap Amalan Terbaik untuk Menyalin Dalam Tatasusunan PHP: Temui Kaedah Cekap Apr 30, 2024 pm 03:42 PM

Amalan terbaik untuk melaksanakan salinan dalam tatasusunan dalam PHP ialah menggunakan json_decode(json_encode($arr)) untuk menukar tatasusunan kepada rentetan JSON dan kemudian menukarnya kembali kepada tatasusunan. Gunakan unserialize(serialize($arr)) untuk mensiri tatasusunan kepada rentetan dan kemudian menyahsirikannya kepada tatasusunan baharu. Gunakan RecursiveIteratorIterator untuk melintasi tatasusunan berbilang dimensi secara rekursif.

Amalan pengisihan pelbagai dimensi tatasusunan PHP: daripada senario mudah kepada kompleks Amalan pengisihan pelbagai dimensi tatasusunan PHP: daripada senario mudah kepada kompleks Apr 29, 2024 pm 09:12 PM

Pengisihan tatasusunan berbilang dimensi boleh dibahagikan kepada pengisihan lajur tunggal dan pengisihan bersarang. Pengisihan lajur tunggal boleh menggunakan fungsi array_multisort() untuk mengisih mengikut lajur pengisihan bersarang memerlukan fungsi rekursif untuk merentasi tatasusunan dan mengisihnya. Kes praktikal termasuk pengisihan mengikut nama produk dan pengisihan kompaun mengikut volum jualan dan harga.

Aplikasi fungsi pengelompokan tatasusunan PHP dalam pengisihan data Aplikasi fungsi pengelompokan tatasusunan PHP dalam pengisihan data May 04, 2024 pm 01:03 PM

Fungsi array_group_by PHP boleh mengumpulkan elemen dalam tatasusunan berdasarkan kekunci atau fungsi penutupan, mengembalikan tatasusunan bersekutu dengan kuncinya ialah nama kumpulan dan nilainya ialah tatasusunan elemen kepunyaan kumpulan.

Algoritma penggabungan tatasusunan PHP dan penyahduplikasian: penyelesaian selari Algoritma penggabungan tatasusunan PHP dan penyahduplikasian: penyelesaian selari Apr 18, 2024 pm 02:30 PM

Algoritma penggabungan tatasusunan dan penyahduplikasian PHP menyediakan penyelesaian selari, membahagikan tatasusunan asal kepada blok kecil untuk pemprosesan selari, dan proses utama menggabungkan hasil blok untuk nyahduplikasi. Langkah-langkah algoritma: Pisahkan tatasusunan asal kepada blok kecil yang diperuntukkan sama. Proses setiap blok untuk penyahduplikasian secara selari. Gabungkan hasil blok dan nyahduplikasi semula.

Peranan fungsi pengelompokan tatasusunan PHP dalam mencari elemen pendua Peranan fungsi pengelompokan tatasusunan PHP dalam mencari elemen pendua May 05, 2024 am 09:21 AM

Fungsi array_group() PHP boleh digunakan untuk mengumpulkan tatasusunan dengan kunci yang ditentukan untuk mencari elemen pendua. Fungsi ini berfungsi melalui langkah berikut: Gunakan key_callback untuk menentukan kunci kumpulan. Secara pilihan, gunakan value_callback untuk menentukan nilai kumpulan. Kira elemen terkumpul dan kenal pasti pendua. Oleh itu, fungsi array_group() sangat berguna untuk mencari dan memproses elemen pendua.

See all articles