ホームページ  >  記事  >  バックエンド開発  >  PHP7の基本的な変数について話しましょう

PHP7の基本的な変数について話しましょう

藏色散人
藏色散人転載
2021-09-16 15:15:341641ブラウズ

変数の基本構造

PHP 変数は弱く型指定されており、変数を指定する必要がないことは誰もが知っています。宣言するときにタイプします。では、これはどのように実装されるのでしょうか?これは変数の基本構造から始める必要があります。

zval の実装

ソース コード ファイル zend_type.h で、zval の定義を確認できます。

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     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 */
        uint32_t     access_flags;         /* class constant access flags */
        uint32_t     property_guard;       /* single property guard */
        uint32_t     extra;                /* not further specified */
    } u2;
}

zval 構造体は、以下を保持する値またはポインターで構成されます。変数のタイプ。共用体 zend_value と 2 つの共用体 u1 および u2 形式

  • u1

u1 は、変数のタイプとその情報、および内部のフィールドを保存するために使用されます。用途は次のとおりです。

type: レコード変数の型。 u2.v.type: 変数の固有の型に対応するフラグ (定数型、参照カウント型、不変型など) を介して

type_flags にアクセスできます。変数の型が異なれば、フラグも異なります。

const_flags: 定数型フラグ

reserved: 予約済みフィールド

  • u2

u2 は主に補助関数です。構造 メモリはアライメントされているため、u2 のスペースは u2 の有無にかかわらずすでにスペースを占有しているため、それが使用されます。 u2 の補助フィールドには多くの型情報が記録されます。これは内部関数にとって非常に有益であり、キャッシュの使いやすさを向上させたり、メモリのアドレス指定操作を減らしたりします。ここではその一部を紹介します。

next: ハッシュ競合の問題 (ハッシュ競合はまだ理解されていません) を解決し、競合の次の要素の位置を記録するために使用されます。

cache_slot: ランタイムキャッシュ。関数を実行すると、まずキャッシュ内を検索し、キャッシュ内に見つからない場合は、グローバル関数テーブル内を検索します。

num_args: 関数の呼び出し時に渡されるパラメータの数

access_flags: public protected private などのオブジェクト クラスのアクセス フラグ。

  • zend_value
typedef union _zend_value {
    zend_long         lval;                /* 整型*/
    double            dval;                /* 浮点型 */
    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;

zend__value からわかるように、long 型と double 型は値を直接格納しますが、他の型はそれぞれの構造体を指すポインターです。したがって、zval の構造により、変数に割り当てる値の型に関係なく、対応する記憶構造を見つけるのに役立つため、PHP 変数は宣言時に型を明示的に指定する必要がありません。

値が文字列である変数を例にとると、その構造は次のとおりです:

PHP5 と PHP7 の zval 構造の比較

  • PHP5
  • PHP7

php7 の zval は合計 16 バイトしか占有しないことがわかります。これにより、PHP5 の zval が占有する 48 バイトと比較して、多くのメモリが節約されます。 。

また、PHP5では変数はすべてヒープに配置されますが、一時変数についてはヒープに適用する必要はありません。したがって、これは PHP7 で最適化されており、一時変数はスタックに直接適用されます。

一般的な変数のタイプ

以下では、変数構造の一般的なタイプをいくつか紹介します。その他のタイプについては、ソース コードをご自身で参照してください。

整数と浮動小数点型

整数と浮動小数点型の場合、スペースが小さいため、整数値は zval に直接格納され、浮動小数点型に格納されます。 type 値は dval に格納されます。

typedef union _zend_value {
    zend_long         lval;             /* 整型*/
    double            dval;             /* 浮点型 */
    ... 
 }

String

PHP 7 では新しい文字列構造が定義されています。構造は次のとおりです。

struct _zend_string {
    zend_refcounted_h ;
    zend_ulong        h;                /* hash value */
    size_t            len;
    char              val[1];
};

上記の各フィールドの意味:

gc: 変数参照情報。参照カウントを使用するすべての変数タイプがこの構造になります。

h: 配列内のインデックスを計算するときに使用されるハッシュ値。 (この操作により PHP7 のパフォーマンスが 5% 向上すると言われています)

len: 文字列の長さ、この値によってバイナリのセキュリティが確保されます

val: 文字列の内容、可変長の構造体、プレスlen の長さを割り当てる場合、メモリに適用されます
array

array は、PHP の非常に強力なデータ構造です。その基礎となる実装は、通常の順序付けされた HashTable です。ここでは、その構造を簡単に説明します。詳細については後ほど説明します。

typedef struct _zend_array HashTable;


struct _zend_array {
    zend_refcounted_h gc;
    union {
        struct {
            ZEND_ENDIAN_LOHI_4(
                zend_uchar    flags,
                zend_uchar    nApplyCount,
                zend_uchar    nIteratorsCount,
                zend_uchar    consistency)
        } v;
        uint32_t flags;
    } u;
    uint32_t          nTableMask;
    Bucket           *arData;
    uint32_t          nNumUsed;
    uint32_t          nNumOfElements;
    uint32_t          nTableSize;
    uint32_t          nInternalPointer;
    zend_long         nNextFreeElement;
    dtor_func_t       pDestructor;
}

オブジェクト

PHP7 のオブジェクト構造も再設計されており、PHP5 の実装とは大きく異なります。

struct _zend_object {
    zend_refcounted_h gc;
    uint32_t          handle;
    zend_class_entry *ce; 
    const zend_object_handlers *handlers;
    HashTable        *properties; 
    zval              properties_table[1];
};

ここにいくつかのフィールドがあります:

gc: gc header

*ce: オブジェクト クラスに対応するクラス

*properties: HashTable Structure 、keyはオブジェクトの属性名、valueはproperties_tables配列内の属性値のオフセットであり、対応する属性値はオフセットを通じてproperties_talbeで見つかります。

properties_talbe[1]: オブジェクトの属性値を格納します


わかりました。まずここにこれを書きましょう。

以上がPHP7の基本的な変数について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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