ホームページ >バックエンド開発 >PHPチュートリアル >PHP変数の徹底解説 storage_PHPチュートリアル

PHP変数の徹底解説 storage_PHPチュートリアル

WBOY
WBOYオリジナル
2016-07-21 15:07:13988ブラウズ

1.1.1 zval 構造体
Zend は zval 構造体を使用して PHP 変数の値を保存します。構造体は次のとおりです:

コードをコピーします コードは次のとおりです:

typedef Union _zvalue_value {
long lval; /* long 値 */
double dval; /* double 値 */
struct {
char *val;
int len;
} str;
HashTable *ht; /* ハッシュテーブル値 */
zend_object_value obj;
} zvalue_value;

struct _zval_struct {
/* 変数情報 */
zvalue_value value; /* 値 */
zend_uint refcount;
zend_uchar type; /* アクティブな型 */
zend_uchar is_ref;
};

typedef struct _zval_struct zval;



Zend根据type值来决定访问value的哪个成员,可用值如下:

IS_NULL

N/A

IS_LONG

对应value.lval

IS_DOUBLE

对应value.dval

IS_STRING

对应value.str

IS_ARRAY

对应value.ht

IS_OBJECT

对应value.obj

IS_BOOL

对应value.lval.

IS_RESOURCE

对应value.lval

この表から 2 つの興味深いことが分かります: 1 つ目は、PHP の配列は実際には HashTable であり、これが PHP が連想配列をサポートできる理由を説明しています 2 つ目は、Resource は Long 値であり、そこに格納されるのは通常ポインタです。内部配列、または作成者だけが知っているその他のものは、ハンドルと見なすことができます。

1.1.2 参照カウント
参照カウントは、ガベージ コレクション、メモリ プール、文字列などで広く使用されています。Zend は典型的な参照カウントを実装しています。複数の PHP 変数は、参照カウント メカニズムを通じて同じ zval を共有できます。zval の残りの 2 つのメンバー is_ref と refcount は、この共有をサポートするために使用されます。
明らかに、refcount はカウントに使用され、参照が増加または減少すると、この値もそれに応じて増加または減少し、ゼロに減少すると、Zend は zval をリサイクルします。
is_ref についてはどうですか?

1.1.3 zval status
PHP には、参照変数と非参照変数の 2 種類の変数があり、それらはすべて参照カウントを使用して Zend に保存されます。非参照変数の場合、変数は相互に独立している必要があり、1 つの変数を変更する場合、変数を書き込むときに、コピーオンライト メカニズムを使用することでこの競合を解決できます。 Zend は、この変数が指す zval が複数の変数で共有されている場合、refcount が 1 の zval がそこにコピーされ、元の zval の refcount がデクリメントされます。このプロセスは「zval 分離」と呼ばれます。ただし、参照変数の場合は、非参照型の要件とは逆になります。1 つの変数を変更すると、バンドルされたすべての変数が変更される必要があります。
これら 2 つの状況にそれぞれ対処するには、現在の zval のステータスを指摘する必要があることがわかります。 is_ref は、現在 zval を指しているすべての変数が参照によって割り当てられているかどうかを指摘します。すべての参照またはなし。このとき、別の変数が変更された場合、その zval の is_ref が 0、つまり参照ではないことが判明した場合にのみ、Zend は Copy-On-Write を実行します。

1.1.4 zval 状態の切り替え
zval に対するすべての代入操作が参照または非参照である場合、1 つの is_ref で十分に対応できます。ただし、世界は常にそれほど美しいとは限りません。参照代入と非参照代入を混在させる場合、PHP はユーザーにそのような制限を課すことができません。
状況 I、次の PHP コードを見てください:

コードをコピーします コードは次のとおりです:

$a = 1;
$b = $a;
$c = $b;
$d = &$c; // 多数の非参照代入に参照を挿入します
?>

このコードは最初に初期化を実行し、新しい zval is_ref=0 を作成します。 refcount=1、そして、a をこの zval にポイントし、その後に 2 つの非参照代入が続きます。b と c を a の zval にポイントするだけです。最後の行は、is_ref が 1 である必要があります。 Zend は、c が zval を指すことは参照型ではないことを発見したため、c に対して別の zval を作成し、同時に d が zval を指すようにしました。
本質的に、これは単なる値ではなく、コピーオンライトとして見ることもできます。is_ref も保護されたオブジェクトです。
プロセス全体を以下に示します:

ケース II、次の PHP コードを見てください:

コードをコピーします コードは次のとおりです:

$a = 1;
$b = &$a;
$c = &$b;
$d = $c; // 一連の参照代入に非参照を挿入します
?>

このコードの最初の 3 文は、a、b、c が zval を指すようにします。 with is_ref=1, refcount =3; 4 番目の文は非参照代入ですが、ターゲット zval は単に参照変数を増やすだけです。解決策は、d の別のコピーを生成することです。
全体のプロセスは次のとおりです:

1.1.5 パラメータの受け渡し
PHP関数のパラメータの受け渡しは、変数の代入と同じであり、非参照の受け渡しは非参照の代入と同等であり、参照の受け渡しは参照の代入と同等であり、実行につながる場合もあります。 zval 状態切り替えの。これについては後述します。

www.bkjia.com本当http://www.bkjia.com/PHPjc/327575.html技術記事 1.1.1 zval 構造体 Zend は zval 構造体を使用して PHP 変数の値を保存します。 構造体は次のとおりです。 次のようにコードをコピーします。 typedef Union _zvalue_value { long lval;/* long value */ double...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。