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.
Änderung beim Schreiben
PHP verwendet Referenzzählung, um eine einfache Speicherbereinigung durchzuführen:
<?php1. $val = "laruence";2. $ref = &$val;3. $copy = $val;?>
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
“
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!