ホームページ >バックエンド開発 >PHP7 >PHP7の基本的な変数をマスターする

PHP7の基本的な変数をマスターする

coldplay.xixi
coldplay.xixi転載
2020-11-17 16:40:542542ブラウズ

PHP7 列では、関連する基本変数を紹介します。

PHP7の基本的な変数をマスターする

変数の基本構造

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 変数は宣言時に型を明示的に指定する必要がありません。

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

PHP7の基本的な変数をマスターする
##zval 構造の比較PHP5 および PHP7

#PHP5
PHP7の基本的な変数をマスターする
##PHP7
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

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

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