ホームページ >バックエンド開発 >PHP7 >PHP7カーネルの詳細説明を参照

PHP7カーネルの詳細説明を参照

Guanhui
Guanhui転載
2020-06-06 09:20:232678ブラウズ

PHP7カーネルの詳細説明を参照

問題

参照 (REFERENCE) は PHP5 ではフラグでしたが、PHP7 以降はそれを新しい型 IS_REFERNCE に変更しました。参照は非常に一般的なアプリケーションであるため、この変更により多くの変更がもたらされ、PHP7 の開発時に誤ってこの型の処理を忘れる原因にもなり、多くの問題が発生しました。バグがたくさんあります。

最も単純なケースは、さまざまな型を扱う場合です。今後、この新しい型についてさらに考慮する必要があります。たとえば、PHP7 では、このコード形式は非常にわかりにくくなります。共通:

try_again:swtich (Z_TYPE_P(zv)) { case IS_TRING: ブレーク; case IS_ARRAY: ブレーク; ... case IS_REFERENCE: zv = Z_REFVAL_P(zv); // 逆参照 goto try_again; ブレーク ;}

独自の拡張機能を作成し、この新しい型を考慮することを忘れると、問題が発生します。

なぜですか?

では、この新しい型は非常に多くの問題を引き起こすため、なぜ参照を型に変換するためにそれを使用します? なぜ単にフラグを使用しないのでしょうか?
一言で言えば、これを行う必要があるのは私たちです。 -_
#前述したように、Hashtable は zval を直接格納します。シンボル テーブル、2 つの zval が値を共有するにはどうすればよいですか? 文字列などの複合型の場合は問題ありませんが、問題を解決するための参照であることを示すフラグ ビットを zend_refcounted 構造体に追加できるようです。 Change On Write によるコピーも発生しますが、PHP7 では、IS_LONG などの一部の型は zval に直接格納されることがわかっていますが、参照型には参照カウントが必要です。そのため、IS_LONG および IS_REFERNCE である zval をどのように表現すればよいでしょうか?
このため、この新しい型を作成しました:
PHP7カーネルの詳細説明を参照図に示すように、Reference は新しい型です: zend_reference.IS_REFERNCE 型の zval の場合、zval.value.ref は zend_reference へのポインターであり、これには次のものが含まれます。参照カウントと zval。zval の特定の値は .
の zval.value.ref->val に格納されます。したがって、IS_LONG の参照には、zend_reference を指す IS_REFERNCE 型の zval を使用します。この zend_reference->val は、IS_LONG 型の zval です。

Change On Write

PHP は参照カウントを使用して単純なガベージ コレクションを実行します。次のコードを考えてみましょう:

<?php1. $val = "laruence";2. $ref = &$val;3. $copy = $val;?>

$ref と $val は同じものを指します。 zval の参照については、PHP5 では、参照カウント 2 と参照フラグ 1 によってこの状況を表しました。 $val を $copy(line) にコピーするとき3) $val が 1 より大きいカウントの参照であることがわかり、書き込み時の変更、つまり分離が必要なので、この zval をコピーする必要があります。
PHP7 では、状況はさらに大きくなります。まず、$ref(2行目)に参照を代入すると、IS_REFERNCE型が生成され、このとき参照する変数が2つあるため、zend_reference構造体の参照カウントはzval.value.ref->gcとなります。 refcount は 2.
その後、$ に割り当てられます。コピーすると (3 行目)、$val が参照であることがわかり、$copy は zval.value.ref->val を指します。これは zval です。その文字列値は laruence であり、zval の参照を 1 ずつカウントします。つまり、zval.value.ref->val.value.str.gc.refcount は 2 です。コピーは発生しません。
これは効果的に問題を解決します。前の章で説明した PHP5 の古典的な問題。たとえば、前の章の問題を PHP7 で実行すると、得られる結果は次のとおりです:

$ php-7.0/sapi/cli/php /tmp/1.phpUsed 0.00021380008539Used 0.00020173048281

コピーが発生していないことがわかります。パフォーマンスに問題はありません。

推奨チュートリアル :PHP>>

以上がPHP7カーネルの詳細説明を参照の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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