PHP-Warnung: Die Referenzzeit für die Anrufzeit ist veraltet

73

Ich erhalte die Warnung: Call-time pass-by-reference has been deprecatedfür die folgenden Codezeilen:

function XML() {
    $this->parser = &xml_parser_create();
    xml_parser_set_option(&$this->parser, XML_OPTION_CASE_FOLDING, false);
    xml_set_object(&$this->parser, &$this);
    xml_set_element_handler(&$this->parser, 'open','close');
    xml_set_character_data_handler(&$this->parser, 'data');
}
function destruct() {
    xml_parser_free(&$this->parser);
}
function & parse(&$data) {
    $this->document = array();
    $this->stack    = array();
    $this->parent   = &$this->document;
    return xml_parse(&$this->parser, &$data, true) ? $this->document : NULL;
}

Was verursacht es und wie kann es behoben werden?

yohannan_sobin
quelle
Verwandte Handbuchseite: Passing by Reference
Palec

Antworten:

143

&Von &$thisüberall entfernen , es wird nicht benötigt. Tatsächlich denke ich, dass Sie &diesen Code überall entfernen können - er wird überhaupt nicht benötigt.

Lange Erklärung

PHP ermöglicht die Übergabe von Variablen auf zwei Arten: "nach Wert" und "nach Referenz". Erster Weg ("nach Wert"), Sie können sie nicht ändern, anderer zweiter Weg ("nach Referenz") können Sie:

     function not_modified($x) { $x = $x+1; }
     function modified(&$x) { $x = $x+1; }

Beachten Sie das &Schild. Wenn ich modifiedeine Variable aufrufe, wird sie geändert, wenn ich sie aufrufe not_modified, nachdem sie zurückgegeben wurde, ist der Wert des Arguments der gleiche.

Ältere Versionen von PHP können das Verhalten von modifiedmit simulieren, not_modifiedindem Sie Folgendes tun : not_modified(&$x). Dies ist "Anrufzeit als Referenz". Es ist veraltet und sollte niemals verwendet werden.

Wenn Sie in sehr alten PHP-Versionen (lesen Sie: PHP 4 und früher) Objekte ändern, sollten Sie diese als Referenz übergeben, also die Verwendung von &$this. Dies ist weder notwendig noch empfehlenswert, da Objekte immer geändert werden, wenn sie an function übergeben werden, dh dies funktioniert:

   function obj_modified($obj) { $obj->x = $obj->x+1; }

Dies würde sich ändern $obj->x, obwohl es formal "nach Wert" übergeben wird, aber was übergeben wird, ist das Objekthandle (wie in Java usw.) und nicht die Kopie des Objekts, wie es in PHP 4 war.

Dies bedeutet, dass Sie, es sei denn, Sie tun etwas Seltsames, fast nie ein Objekt übergeben müssen (und somit als $thisReferenz, sei es zur Anrufzeit oder auf andere Weise). Insbesondere benötigt Ihr Code es nicht.

StasM
quelle
Darf ich auch darauf hinweisen, dass der oben genannte Fehler angezeigt wird, wenn Sie versuchen, eine Funktion mit aufzurufen, call_user_func('myfunc', &$param)aber nicht, wenn Sie verwenden call_user_func_array('myfunc', array(&$param)). Ich weiß aber nicht warum , wenn jemand Licht ins Dunkel bringen will :)
Matt Fletcher
1
@MattFletcher Da es sich bei der ersteren um eine Anrufzeitreferenzsyntax handelt, die seit langem veraltet ist. Letzteres übergibt nur Argumente an eine Funktion (die zufällig call_user_func_array ist), sodass daran nichts auszusetzen ist. Ja, Sie können diese letztere Syntax verwenden, um eine Anrufzeitreferenz unter dem Radar durchzuführen, oder Sie können sie für legitime Zwecke verwenden - beispielsweise zum Erstellen von Wrappern für by-ref-Variablenargumentfunktionen (parametrisierte Bindungen in PDO können dies sein) ein Beispiel). Der Unterschied ist erstere ist immer nicht legitim und wird nicht benötigt, letztere kann je nach Verwendung legitim oder nicht legitim sein.
StasM
2
First way, you can modify them, other way you can'tumgekehrt :)
Thierry J.
20

Nur für den Fall, dass Sie sich fragen, ist eine Anrufzeit als Referenz eine veraltete PHP-Funktion, die die lose Eingabe von PHP fördert. Grundsätzlich können Sie eine Referenz (ähnlich einem C-Zeiger) an eine Funktion übergeben, die nicht speziell nach einer solchen gefragt hat. Es ist PHPs Lösung für den quadratischen Stift in einem Problem mit runden Löchern.
In Ihrem Fall niemals referenzieren $this. Außerhalb einer Klasse können Sie durch einen Verweis auf ihre Klasse $thisnicht auf ihre privaten Methoden und Felder zugreifen.

Beispiel:

<?php
function test1( $test ) {} //This function doesn't want a reference
function test2( &$test ) {} //This function implicitly asks for a reference

$foo = 'bar';
test2( $foo ); //This function is actually given a reference
test1( &$foo ); //But we can't force a reference on test1 anymore, ERROR
?>
Bailey Parker
quelle
3
"Grundsätzlich können Sie eine Referenz (ähnlich einem C-Zeiger) an eine Funktion übergeben, die nicht speziell nach einer solchen gefragt hat." <- Das ist das Gute. Vielen Dank.
RobW
Um ganz klar zu sein, PHP-Referenzen sind überhaupt keine C-Zeiger. Sie ähneln eher UNIX-Hardlinks, wenn Sie eine Analogie benötigen.
StasM