ホームページ  >  記事  >  バックエンド開発  >  この記事では、php7 の zval を分析します。

この記事では、php7 の zval を分析します。

藏色散人
藏色散人転載
2021-09-15 17:15:103020ブラウズ

Zval は、PHP で最も重要なデータ構造の 1 つで、PHP の変数の値と型に関する情報が含まれています。

1. zval

1.1 zval の構造 (zend_types.h)

typedef struct _zval_struct     zval;struct _zval_struct {
    zend_value        value;            /* value */
    union {
        struct {
            ZEND_ENDIAN_LOHI_4(
                zend_uchar    type,         /* active type */
                zend_uchar    type_flags,
                zend_uchar    const_flags,
                zend_uchar    reserved)     /* call info for EX(This) */
        } v;
        uint32_t type_info;
    } u1;
    union {
        uint32_t     var_flags;
        uint32_t     next;                 /* hash collision chain */
        uint32_t     cache_slot;           /* literal cache slot */
        uint32_t     lineno;               /* line number (for ast nodes) */
        uint32_t     num_args;             /* arguments number for EX(This) */
        uint32_t     fe_pos;               /* foreach position */
        uint32_t     fe_iter_idx;          /* foreach iterator index */
    } u2;};

zval の構造は比較的単純で、次の 3 つの部分で構成されます:

  • zend_value: 特定の変数型の値またはポインターを保存します
  • u1 の中心的な機能は型を区別することです
  • u2 は補助値です
#zval をより直感的に見るために 構造とコアフィールドの値は上の図のとおりです。


この記事では、php7 の zval を分析します。

u1.v.type の説明:

    IS_UNDEF: マークは未定義で、データが上書きまたは削除できることを示します。たとえば、配列要素に対して unset 操作を実行する場合、PHP 7 は HashTable に割り当てられたメモリからデータを直接削除せず、その代わりに、要素が配置されているバケットの場所を最初に IS_UNDEF としてマークします。 HashTable 内の IS_UNDEF 要素の数は、特定のしきい値に達すると、IS_UNDEF でマークされた要素が再ハッシュ操作中に上書きまたは削除されます。
  1. IS_TRUE と IS_FALSE: ここでは IS_BOOL が 2 つに最適化されており、Boolean 型タグが type に直接記録されます。
  2. IS_REFERENCE: 新しい型です。PHP7 では「&」を処理するために別の処理方法が使用されます。
  3. IS_INDIRECT: これも新しい型です。PHP 7 では HashTable の設計が異なるため、 PHP5 とは大きな違いがあるため、グローバル シンボル テーブルが CV 変数テーブルにアクセスする問題を解決するために、IS_INDRECT 型が導入されました。
  4. IS_PTR: この型はポインター型として定義され、value.ptr の解析に使用され、通常は関数型で使用されます。たとえば、関数またはメソッドを宣言します。
1.2 zend_value

zval の zend_value の定義は次のとおりです:

typedef union _zend_value {
    zend_long         lval;             /* long value */
    double            dval;             /* double value */
    zend_refcounted  *counted;
    zend_string      *str;
    zend_array       *arr;
    zend_object      *obj;
    zend_resource    *res;
    zend_reference   *ref;
    zend_ast_ref     *ast;
    zval             *zv;
    void             *ptr;
    zend_class_entry *ce;
    zend_function    *func;
    struct {
        uint32_t w1;
        uint32_t w2;
    } ww;
} zend_value;
1.3 zval のメモリ使用量

zval 内:

    zend_value は共用体であり、8 バイトのみを占有します。 zend_long、double、またはポインタを格納するのに十分です。
  • u1 は 4 バイトで、v または type_info を格納します。
  • u2 は 4 バイト

この記事では、php7 の zval を分析します。

つまり、zval は 16 バイトを占有します。 。これに対応して、php5 では zval のサイズは 48 バイトとなり、これは確かに大幅な改善です。

2. 変数ストレージ

2.1 true、false、null

は、zend_value の関与なしで zval.u1.v.type に従って直接区別できます

2.2 long、double

は、zend_value の lval または dval に直接格納されます。

2.3 その他の型 (文字列、配列、オブジェクト、リソースなど)

zend_value に対応するポインタを使用して、その特定の構造体を指します。

たとえば、文字列型の構造は

struct _zend_string {
    zend_refcounted_h gc;
    zend_ulong        h;                /* hash value */
    size_t            len;
    char              val[1];
};
です。文字列変数のメモリ構成は次の図に示すように、zval.value.str は zend_string 構造体を指します。


この記事では、php7 の zval を分析します。

Zval は PHP で最も重要なデータ構造の 1 つであり、変数の値が含まれます。 PHP および型関連の情報。

推奨学習: 「

PHP7 チュートリアル

以上がこの記事では、php7 の zval を分析します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。