Bagaimanakah PHP menyimpan pembolehubah? Adakah anda memahami struktur zval?

藏色散人
Lepaskan: 2023-04-11 06:34:02
ke hadapan
4613 orang telah melayarinya

zval dalam kod sumber PHP

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;                                           |
};                                                  |
Salin selepas log masuk

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;
Salin selepas log masuk

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
Salin selepas log masuk

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!

Label berkaitan:
sumber:learnku.com
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan