Ich denke , die Beispiele (oder Logik) könnten falsch herum in der Frage sein, da das 2. Beispiel ( get_arr()Funktion) hat den strengen Standards Hinweis (getestet PHP 5.2 und PHP 5.5) erzeugen.
StrictStandards:Only variables should be passed by reference in`test.php` on line 14
array(2){[0]=>int(1)[1]=>int(2)}
Der Grund? Die test::get_arr()Methode ist keine Variable und im strengen Modus wird eine Warnung generiert. Dieses Verhalten ist äußerst unintuitiv, da die get_arr()Methode einen Array-Wert zurückgibt .
Um diesen Fehler im strengen Modus zu umgehen, ändern Sie entweder die Signatur der Methode, sodass keine Referenz verwendet wird:
function test_arr($a){
var_dump($a);}
Da Sie die Signatur von nicht ändern array_shiftkönnen, können Sie auch eine Zwischenvariable verwenden:
@ user198729: Ich habe nach einer Erklärung oder einem Fix gesucht und festgestellt, dass Sie current () für das erste Element verwenden können. Leider funktioniert end () nicht für das letzte Element, da es "den internen Zeiger auf das letzte Element vorschiebt". current (array_reverse (somefunction ())) funktioniert (ja, es ist albern)
MSpreij
1
Bei Verwendung currentwird davon ausgegangen, dass sich der Array-Zeiger am ersten Element befindet. In den meisten Fällen kann dies eine gültige Annahme sein, auf die Sie jedoch achten sollten.
cmbuckley
1
@leepowers Natürlich würde es dann das gleiche Problem geben, da array_shift()erwartet wird, dass ein Verweis
geändert wird
1
@ user198729 Sie können den $intermediateWert vermeiden, indem Sie ein zusätzliches Klammerpaar verwenden. $el = array_shift( ( get_arr() ) );. Siehe stackoverflow.com/questions/9848295/…
Chloe
1
@Chloe Dies ist die brillanteste Lösung, die ich je gesehen habe, um den Code einfach zu halten !! Danke dir!
Hargobind
7
$instance->find() Gibt einen Verweis auf eine Variable zurück.
Sie erhalten den Bericht, wenn Sie versuchen, diese Referenz als Argument für eine Funktion zu verwenden, ohne sie zuvor in einer Variablen zu speichern.
Dies hilft, Speicherlecks zu vermeiden und wird wahrscheinlich in den nächsten PHP-Versionen zu einem Fehler.
Ihr zweiter Codeblock würde einen Fehler auslösen, wenn er wie folgt geschrieben würde (beachten Sie die &in der Funktionssignatur):
Es sollte jetzt funktionieren (überprüft). Um eine Referenz zurückzugeben, müssen Sie diese bei der Methodensignatur deklarieren, nicht bei der Rückgabe (mein Fehler).
Sagi
Nein, ich kann die Signatur nicht ändern. Die Zwischenvariable von @ pygorex1 kann dies lösen, sieht aber überflüssig aus, nicht wahr?
user198729
Ich weiß, dass Sie die Signatur nicht ändern können. Ich habe nur erklärt, wie es passiert. Sie müssen eine temporäre (= Zwischen-) Variable verwenden, können dies jedoch in derselben Zeile tun. Schauen Sie sich mein zweites Code-Snippet an.
Sagi
4
Ich habe Ihr zweites Snippet ausprobiert, es funktioniert nicht. Es funktioniert nur in einer separaten Zeile
user198729
3
Tatsächlich. Eine Zuordnung gibt den zugewiesenen Wert zurück . array_shift($tmp = $instance->find(..))weist den Wert von $instance->find(..)zu $tmpund übergibt dann den Wert der Zuweisung an array_shift()- was nicht dasselbe ist wie das Übergeben $tmpselbst, also nicht besser als die ursprüngliche Situation ohne die Zuweisung.
Phils
6
Die Fehlerursache ist die Verwendung der internen PHP-Programmierdatenstrukturfunktion array_shift () [php.net/end].
Die Funktion verwendet ein Array als Parameter. Obwohl im Prototyp von array_shift()im Handbuch ein kaufmännisches Und angegeben ist , gibt es in der erweiterten Definition dieser Funktion weder eine Warnhinweisdokumentation noch eine offensichtliche Erklärung dafür, dass der Parameter tatsächlich als Referenz übergeben wird.
Vielleicht ist das / verstanden /. Ich habe es jedoch nicht verstanden, daher war es für mich schwierig, die Fehlerursache zu ermitteln.
Code reproduzieren:
function get_arr(){return array(1,2);}
$array = get_arr();
$el = array_shift($array);
Das zweite Snippet funktioniert auch nicht und deshalb.
array_shiftist eine Modifikatorfunktion, die ihr Argument ändert. Daher wird erwartet, dass sein Parameter eine Referenz ist, und Sie können nicht auf etwas verweisen, das keine Variable ist. Siehe Rasmus 'Erklärungen hier: Strenge Standards: Nur Variablen sollten als Referenz übergeben werden
Es ist möglicherweise nicht die beste Programmierpraxis, alle zu unterdrücken Fehler auf diese Weise , aber in bestimmten Fällen (wie diesem) ist es praktisch und akzeptabel.
Daher bin ich sicher, dass Ihr Freund "Systemadministrator" mit einem weniger verschmutzten zufrieden sein wird error.log.
Ich weiß nicht, wer diese Antwort abgelehnt hat, aber die vorgestellte Lösung funktioniert und es handelt sich um eine PHP-Standardtechnik. Wirklich enttäuschend ... Das nächste Mal könnte ich keine Frage mehr beantworten ... :(
Julio Marchi
5
Ich würde annehmen, dass dies daran liegt, dass das Unterdrücken der Fehlermeldung das Problem mit dem Code nicht behebt. Was werden Sie tun, wenn sich diese Art von Fehler in einer zukünftigen PHP-Version von E_STRICT zu E_ERROR ändert und Ihr Code jetzt nicht ausgeführt wird und auch keine Fehler / Ausgaben erzeugt?
Luke
@TinoDidriksen, ich verstehe und stimme den Gründen zu, von einigen "schlechten Gewohnheiten" abzuraten, insbesondere für die neuen Generationen. Es gibt jedoch eine Ressource, die verwendet werden kann, wenn (und wenn) sie sicher verwendet werden kann und auf den vorgeschlagenen Kontext anwendbar ist. Wenn der Fehlerunterdrücker "@" abgeschafft werden sollte, wäre er aus der Sprache selbst entfernt worden. Gleich wie "eval" (es mag böse sein, aber es hat seine Zwecke). Ich bin dagegen, dass es nicht um die Verwendung einiger Ressourcen geht, sondern um die Verallgemeinerung eines Ratschlags. Insbesondere für den vorgeschlagenen Fall wäre es nicht schädlich, ihn zu verwenden, auch nicht für Debugging-Zwecke.
get_arr()
Funktion) hat den strengen Standards Hinweis (getestet PHP 5.2 und PHP 5.5) erzeugen.Antworten:
Betrachten Sie den folgenden Code:
Dadurch wird die folgende Ausgabe generiert:
Der Grund? Die
test::get_arr()
Methode ist keine Variable und im strengen Modus wird eine Warnung generiert. Dieses Verhalten ist äußerst unintuitiv, da dieget_arr()
Methode einen Array-Wert zurückgibt .Um diesen Fehler im strengen Modus zu umgehen, ändern Sie entweder die Signatur der Methode, sodass keine Referenz verwendet wird:
Da Sie die Signatur von nicht ändern
array_shift
können, können Sie auch eine Zwischenvariable verwenden:quelle
current
wird davon ausgegangen, dass sich der Array-Zeiger am ersten Element befindet. In den meisten Fällen kann dies eine gültige Annahme sein, auf die Sie jedoch achten sollten.array_shift()
erwartet wird, dass ein Verweis$intermediate
Wert vermeiden, indem Sie ein zusätzliches Klammerpaar verwenden.$el = array_shift( ( get_arr() ) );
. Siehe stackoverflow.com/questions/9848295/…$instance->find()
Gibt einen Verweis auf eine Variable zurück.Sie erhalten den Bericht, wenn Sie versuchen, diese Referenz als Argument für eine Funktion zu verwenden, ohne sie zuvor in einer Variablen zu speichern.
Dies hilft, Speicherlecks zu vermeiden und wird wahrscheinlich in den nächsten PHP-Versionen zu einem Fehler.
Ihr zweiter Codeblock würde einen Fehler auslösen, wenn er wie folgt geschrieben würde (beachten Sie die
&
in der Funktionssignatur):Eine schnelle (und nicht so schöne) Lösung wäre also:
Grundsätzlich weisen Sie zuerst eine temporäre Variable zu und senden die Variable als Argument.
quelle
array_shift($tmp = $instance->find(..))
weist den Wert von$instance->find(..)
zu$tmp
und übergibt dann den Wert der Zuweisung anarray_shift()
- was nicht dasselbe ist wie das Übergeben$tmp
selbst, also nicht besser als die ursprüngliche Situation ohne die Zuweisung.Die Fehlerursache ist die Verwendung der internen PHP-Programmierdatenstrukturfunktion array_shift () [php.net/end].
Die Funktion verwendet ein Array als Parameter. Obwohl im Prototyp von
array_shift()
im Handbuch ein kaufmännisches Und angegeben ist , gibt es in der erweiterten Definition dieser Funktion weder eine Warnhinweisdokumentation noch eine offensichtliche Erklärung dafür, dass der Parameter tatsächlich als Referenz übergeben wird.Vielleicht ist das / verstanden /. Ich habe es jedoch nicht verstanden, daher war es für mich schwierig, die Fehlerursache zu ermitteln.
Code reproduzieren:
quelle
Dieser Code:
Muss geändert werden in:
quelle
Das zweite Snippet funktioniert auch nicht und deshalb.
array_shift
ist eine Modifikatorfunktion, die ihr Argument ändert. Daher wird erwartet, dass sein Parameter eine Referenz ist, und Sie können nicht auf etwas verweisen, das keine Variable ist. Siehe Rasmus 'Erklärungen hier: Strenge Standards: Nur Variablen sollten als Referenz übergeben werdenquelle
In solchen offensichtlichen Fällen können Sie PHP jederzeit anweisen, Nachrichten zu unterdrücken, indem Sie "@" vor der Funktion verwenden.
Es ist möglicherweise nicht die beste Programmierpraxis, alle zu unterdrücken Fehler auf diese Weise , aber in bestimmten Fällen (wie diesem) ist es praktisch und akzeptabel.
Daher bin ich sicher, dass Ihr Freund "Systemadministrator" mit einem weniger verschmutzten zufrieden sein wird
error.log
.quelle