PHP 変数は弱い型指定があり、宣言時に型を指定する必要がないことは誰もが知っています。では、これはどのように実装されるのでしょうか?これは変数の基本構造から始める必要があります。
ソース コード ファイル 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 は、変数のタイプとその情報、および内部のフィールドを保存するために使用されます。用途は次のとおりです。
type: レコード変数の型。 u2.v.type: 変数の固有の型に対応するフラグ (定数型、参照カウント型、不変型など) を介して
type_flags にアクセスできます。変数の型が異なれば、フラグも異なります。
const_flags: 定数型フラグ
reserved: 予約済みフィールド
u2 は主に補助関数です。構造 メモリはアライメントされているため、u2 のスペースは u2 の有無にかかわらずすでにスペースを占有しているため、それが使用されます。 u2 の補助フィールドには多くの型情報が記録されます。これは内部関数にとって非常に有益であり、キャッシュの使いやすさを向上させたり、メモリのアドレス指定操作を減らしたりします。ここではその一部を紹介します。
next: ハッシュ競合の問題 (ハッシュ競合はまだ理解されていません) を解決し、競合の次の要素の位置を記録するために使用されます。
cache_slot: ランタイムキャッシュ。関数を実行すると、まずキャッシュ内を検索し、キャッシュ内に見つからない場合は、グローバル関数テーブル内を検索します。
num_args: 関数の呼び出し時に渡されるパラメータの数
access_flags: public protected private などのオブジェクト クラスのアクセス フラグ。
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 変数は宣言時に型を明示的に指定する必要がありません。
値が文字列である変数を例にとると、その構造は次のようになります:
##zval 構造の比較PHP5 および PHP7 #PHP5typedef union _zend_value { zend_long lval; /* 整型*/ double dval; /* 浮点型 */ ... }复制代码
struct _zend_string { zend_refcounted_h ; zend_ulong h; /* hash value */ size_t len; char val[1]; };复制代码
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
以上がPHP7の基本的な変数をマスターするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。