Tidak perlu mengisytiharkan jenis semasa mentakrifkan pembolehubah dalam PHP Pada mulanya, nilai integer diberikan kepada pembolehubah $a, dan ia boleh ditukar dengan mudah kepada yang lain jenis nanti. Jadi bagaimana pembolehubah ini $a disimpan dalam kod sumber PHP? Dengan memikirkan soalan ini, mari kita lihat kod sumber PHP.
Kod sumber PHP ditulis dalam C. Struktur zval digunakan dalam kod sumber PHP untuk menyimpan pembolehubah yang dicipta dalam kod PHP. Mari kita keluarkan definisi struktur zval dan menganalisisnya secara ringkas.
Ini ialah repositori rasmi PHP pada Github: github.com/php/php-src Cawangan yang digunakan dalam artikel ini ialah PHP-7.4.29.
zval structure
Cari fail ini dalam kod sumber PHP: php-src/Zend/zend_types.h, anda boleh melihat bahawa struktur zval ditakrifkan seperti berikut , sebelah kiri ialah kod sumber. Kod sumber menggunakan jenis PHP yang ditentukan sendiri zend_uchar, uint16_t, uint32_t, dsb. Jenis ini akan ditukar kepada char short int, dsb. di bawah platform dan penyusun yang berbeza untuk platform. Untuk memudahkan pemahaman, saya menterjemahkannya ke dalam jenis biasa dan memaparkannya di sebelah kanan kod sumber. Pada masa yang sama, fungsi makro ZEND_ENDIAN_LOHI_3() juga dikembangkan.
typedef struct _zval_struct zval; ... 《源代码》 《翻译后》 ------------------------------------------------------------------------------------------- struct _zval_struct { | struct _zval_struct { zend_value value; | zend_value value; union { | union { struct { | struct { ZEND_ENDIAN_LOHI_3( | unsigned char type; zend_uchar type, | unsigned char type_flags; zend_uchar type_flags, | union { union { | unsigned short extra; uint16_t extra; | } u; } u | } v; ) | unsigned int type_info; } v; | } u1; uint32_t type_info; | union { } u1; | unsigned int next; union { | unsigned int cache_slot; uint32_t next; | unsigned int opline_num; uint32_t cache_slot; | unsigned int lineno; uint32_t opline_num; | unsigned int num_args; uint32_t lineno; | unsigned int fe_pos; uint32_t num_args; | unsigned int fe_iter_idx; uint32_t fe_pos; | unsigned int access_flags; uint32_t fe_iter_idx; | unsigned int property_guard; uint32_t access_flags; | unsigned int constant_flags; uint32_t property_guard; | unsigned int extra; uint32_t constant_flags; | } u2; uint32_t extra; | }; } u2; | }; |
Dalam struktur zval, nilai pembolehubah disimpan dalam atribut nilai jenis zend_value. Dan gunakan u1.v.type untuk merekodkan jenis nilai ini Sebagai contoh, IS_LONG sepadan dengan jenis integer dan IS_STRING sepadan dengan jenis rentetan.
zend_value union
Jenis zend_value juga ditakrifkan dalam php-src/Zend/zend_types.h dan ialah kesatuan yang berikut ialah takrifan zend_value , sebelah kiri ialah kod sumber. Juga di sebelah kanan, saya juga membuat terjemahan mudah, menterjemah zend_long uint32_t ke dalam jenis biasa untuk tontonan mudah.
《源代码》 《翻译后》 ------------------------------------------------------------------------------------ typedef union _zend_value { | typedef union _zend_value { zend_long lval; /* long value */ | long lval; double dval; /* double value */ | double dval; zend_refcounted *counted; | zend_refcounted *counted; zend_string *str; | zend_string *str; zend_array *arr; | zend_array *arr; zend_object *obj; | zend_object *obj; zend_resource *res; | zend_resource *res; zend_reference *ref; | zend_reference *ref; zend_ast_ref *ast; | zend_ast_ref *ast; zval *zv; | zval *zv; void *ptr; | void *ptr; zend_class_entry *ce; | zend_class_entry *ce; zend_function *func; | zend_function *func; struct { | struct { uint32_t w1; | unsigned int w1; uint32_t w2; | unsigned int w2; } ww; | } ww; } zend_value; | } zend_value;
Satu ciri kesatuan ialah memori yang didudukinya ialah panjang yang sepadan dengan jenis terbesar dalam atributnya. Antaranya, zend_long adalah jenis panjang Anda boleh melihat bahawa panjang lval jenis panjang dan dval jenis berganda adalah kedua-duanya 8 bait. Jenis penunjuk lain di dalamnya juga 8 bait. Atribut struktur terakhir ww terdiri daripada dua jenis int, dan panjang gabungan juga ialah 8 bait. Oleh itu, panjang kesatuan ini ialah 8 bait.
Dalam kod PHP yang kami tulis, nilai data integer dan titik terapung akan disimpan terus dalam lval dan dval. Jika ia adalah rentetan, tatasusunan atau jenis lain, ruang akan diperuntukkan untuk menyimpan data dan alamatnya akan disimpan dalam zend_value, iaitu atribut zval.value, seperti: zval.value.zend_long = 9527, zval .value.zend_string = alamat String aksara, zval.value.zend_array = alamat tatasusunan. Kemudian tandakan pada zval.u1.v.type bahawa zval.value ini ialah integer, titik terapung, rentetan atau jenis lain.
takrif jenis zval.u1.v.type juga terdapat dalam fail php-src/Zend/zend_types.h Semua definisi adalah seperti berikut:
/* regular data types */ #define IS_UNDEF 0 #define IS_NULL 1 #define IS_FALSE 2 #define IS_TRUE 3 #define IS_LONG 4 #define IS_DOUBLE 5 #define IS_STRING 6 #define IS_ARRAY 7 #define IS_OBJECT 8 #define IS_RESOURCE 9 #define IS_REFERENCE 10 /* constant expressions */ #define IS_CONSTANT_AST 11 /* internal types */ #define IS_INDIRECT 13 #define IS_PTR 14 #define IS_ALIAS_PTR 15 #define _IS_ERROR 15 /* fake types used only for type hinting (Z_TYPE(zv) can not use them) */ #define _IS_BOOL 16 #define IS_CALLABLE 17 #define IS_ITERABLE 18 #define IS_VOID 19 #define _IS_NUMBER 20
struktur zval. memori Diduduki
Seterusnya kita menganalisis memori yang diperlukan oleh zval.
nilai: jenis zend_value 8 bait.
u1:
u1.v.type: unsigned char 1 bait, u1.v.type_flags : unsigned char 1 bait, u1.v.u: Terdapat hanya satu atribut tambahan pendek yang tidak ditandatangani dalam gabungan 2 bait, jadi struktur u1.v ialah 4 bait secara keseluruhan.
u1.type_info: unsigned int 4 bait.
Oleh itu, panjang kesatuan u1 ialah panjang atribut terpanjang: 4 bait.
u2: Ia juga merupakan kesatuan, yang mengandungi atribut jenis int, jadi panjangnya ialah 4 bait.
Jadi jumlah memori yang diduduki oleh zval ialah 8 4 4 = 16 bait.
Maksudnya, apabila kita menulis kod PHP, jika kita mencipta pembolehubah integer, ia sebenarnya akan menduduki 16 bait memori semasa operasi, overhed memori Sekurang-kurangnya dua kali lebih lama daripada C bahasa. Sudah tentu, overhed berganda ini juga membawa fleksibiliti PHP dalam mengendalikan pembolehubah.
Pembelajaran yang disyorkan: "Tutorial Video PHP"
Atas ialah kandungan terperinci Bagaimanakah PHP menyimpan pembolehubah? Adakah anda memahami struktur zval?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!