Heim > Artikel > Backend-Entwicklung > Warum vermeidet das Einschließen eines Funktionsaufrufs in Klammern einen Referenzfehler in PHP?
Mehrdeutiges Funktionsaufrufverhalten in PHP: Die verborgenen Nuancen enthüllen
In PHP tritt ein eigenartiges Verhalten auf, wenn eine Funktion aufgerufen und ihr Ergebnis gekapselt wird in Klammern. Diese scheinbar harmlose Aktion kann die Interpretation des Ergebnisses verändern und möglicherweise zu unerwartetem Verhalten führen.
Bedenken Sie den folgenden Codeausschnitt:
error_reporting(E_ALL | E_STRICT); function get_array() { return array(); } function foo() { return reset(get_array()); // Error: "Only variables should be passed by reference" return reset((get_array())); // Success } foo();
In der ersten Variante wird versucht, das Ergebnis von zuzuordnen get_array() an die Funktion reset() löst einen Fehler aus, da es sich um eine Variable handeln sollte, die als Referenz übergeben wird. Wenn wir den Funktionsaufruf jedoch in Klammern setzen, wird das Skript erfolgreich ausgeführt.
Während man über die zugrunde liegende Mechanik spekulieren könnte, liefert eine gründliche Prüfung der Dokumentation keine explizite Erklärung für dieses Phänomen.
Ein tieferes Eintauchen in die Feinheiten der PHP-Grammatik und die Verwendung von Tools wie phc zur Visualisierung des AST des Codes ergaben, dass beide Snippets zu identischen Analysebäumen führen. Dadurch wird die Möglichkeit ausgeschlossen, dass syntaktische Änderungen das Verhalten beeinflussen.
Eine genauere Betrachtung der PHP-Opcode-Struktur zeigt jedoch einen versteckten Vorbehalt innerhalb des ZEND_SEND_VAR_NO_REF-Opcodes. Dieser Opcode schreibt vor, dass kein Referenzfehler ausgegeben werden soll, wenn das Argument kein Funktionsaufruf ist und einen Referenzzähler von 1 hat.
In der zweiten Variante von foo() wird der Funktionsaufruf nicht mehr als fällig erkannt zu den hinzugefügten Klammern. Infolgedessen klassifiziert das System das Argument als expr_without_variable und initiiert den Opcode SEND_VAR_NO_REF. Da das zurückgegebene Array einen Referenzzähler von 1 hat, gilt es als Variable und vermeidet so den Referenzfehler.
Es ist wichtig zu beachten, dass dieses Verhalten als Fehler und nicht als beabsichtigte Funktion betrachtet werden sollte . Sich auf solche Inkonsistenzen zu verlassen, kann zu unvorhersehbarem und unzuverlässigem Code führen.
Das obige ist der detaillierte Inhalt vonWarum vermeidet das Einschließen eines Funktionsaufrufs in Klammern einen Referenzfehler in PHP?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!