Heim  >  Artikel  >  Backend-Entwicklung  >  Verweisen Sie auf eine detaillierte Erklärung des PHP7-Kernels

Verweisen Sie auf eine detaillierte Erklärung des PHP7-Kernels

Guanhui
Guanhuinach vorne
2020-06-06 09:20:232556Durchsuche

Verweisen Sie auf eine detaillierte Erklärung des PHP7-Kernels

Problem

Referenz (REFERENCE) war ein Flag in PHP5, aber nach PHP7 haben wir es in einen neuen Typ umgewandelt: IS_REFERNCE. Referenzen sind eine sehr häufige Anwendung, daher hat diese Änderung viele Änderungen mit sich gebracht und auch dazu geführt, dass wir bei der Entwicklung von PHP7 versehentlich vergessen haben, mit diesem Typ umzugehen, was viele Fehler verursacht hat.

Der einfachste Fall ist der Umgang mit verschiedenen Typen. Von nun an müssen wir diesen neuen Typ stärker berücksichtigen. In PHP7 wird beispielsweise diese Codeform sehr häufig:

try_again:swtich (Z_TYPE_P(zv )) { case IS_TRING: break; case IS_REFERENCE: zv = Z_REFVAL_P(zv); // Dereferenzierung goto try_again; und vergessen Sie, diesen neuen Typ zu berücksichtigen, er wird Probleme verursachen.

Warum?

Da dieser neue Typ so viele Probleme mit sich bringen wird, warum haben wir den Verweis geändert in einen Typ? Warum nicht einfach ein Flag verwenden?Kurz gesagt, wir müssen das tun -_#

Wie bereits erwähnt, speichert Hashtable direkt Zval, also wie können zwei Zval teilt einen Wert? Für komplexe Typen wie Zeichenfolgen ist dies in Ordnung. Wir können der zend_refcounted-Struktur ein Flag-Bit hinzufügen, um anzuzeigen, dass es sich um eine Referenz handelt. Dies wird jedoch auch durch „Change On“ verursacht Schreiben Sie, aber wir wissen, dass in PHP7 einige Typen direkt in zval gespeichert werden, z. B. IS_LONG. Referenztypen erfordern jedoch eine Referenzzählung. Wie stellt man also einen Zval dar, der IS_LONG und IS_REFERNCE ist?

Aus diesem Grund haben wir dies erstellt neuer Typ:

Wie in der Abbildung gezeigt, ist Reference ein neuer Typ: zval vom Typ IS_REFERNCE, zval.value.ref ist ein Zeiger auf zend_reference, der einen Referenzzähler und einen zval enthält Der spezifische Wert von zval wird in zval.value.ref- >val in gespeichert.
Also verwenden Sie für die IS_LONG-Referenz einen zval vom Typ IS_REFERNCE, der auf eine zend_reference zeigt, und dieser zend_reference->val ist ein zval vom Typ IS_LONG.
Verweisen Sie auf eine detaillierte Erklärung des PHP7-Kernels
Änderung beim Schreiben

PHP verwendet Referenzzählung, um eine einfache Speicherbereinigung durchzuführen:

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

$ref und $val zeigt auf die gleiche Referenz von zval. In PHP5 haben wir diese Situation durch einen Referenzzähler von 2 und ein Referenzflag von 1 dargestellt. Beim Kopieren von $val nach $copy (Zeile 3) haben wir festgestellt, dass $val A ist Referenz mit einer Anzahl größer als 1, daher ist eine Änderung beim Schreiben, also eine Trennung, erforderlich. Daher müssen wir diesen zval kopieren.

In PHP7 wird die Situation viel einfacher. Weisen Sie zunächst die Referenz zu $ref zu (Zeile 2) wird ein IS_REFERNCE-Typ generiert, und da zu diesem Zeitpunkt zwei Variablen darauf verweisen, wird dann der Referenzzähler der zend_reference-Struktur zval.value.ref->gc.refcount 2.

zugewiesen nach $ Beim Kopieren (Zeile 3) wird festgestellt, dass $val eine Referenz ist. Daher zeigt $copy auf zval.value.ref->val, das zval, dessen Zeichenfolgenwert laruence ist, und erhöht dann die Referenzanzahl von zval um 1, d Kapitel Wenn wir beispielsweise das Problem im vorherigen Kapitel unter PHP7 ausführen, erhalten wir folgendes Ergebnis:

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

Es ist ersichtlich, dass kein Kopiervorgang stattfindet, sodass keine Leistungsprobleme auftreten.

Empfohlenes Tutorial: „

PHP

Das obige ist der detaillierte Inhalt vonVerweisen Sie auf eine detaillierte Erklärung des PHP7-Kernels. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:laruence.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen