Der Methodenrückgabewert kann im Schreibkontext nicht verwendet werden

465

Ich würde denken, dass der folgende Code funktionieren sollte, aber er funktioniert nicht (Bearbeitet: Funktioniert jetzt in PHP 5.5+) :

if (!empty($r->getError()))

Wo getError()ist einfach:

public function getError()
{
    return $this->error;
}

Dennoch habe ich diesen Fehler:

Der Methodenrückgabewert kann im Schreibkontext nicht verwendet werden

Was bedeutet das? Ist das nicht nur eine Lektüre?

Extrakun
quelle
2
Wahrscheinlich dürfen Sie in PHP 5.5 Ausdrücke an emptyfolgende Adresse übergeben
Carlos Campderrós
Ok, ich finde die Antwort von porneL auch richtig. Dies ist mein Code if ( !$e->find('div') ) , der prüft, ob das aktuelle HTML-DOM-Element leer ist oder nicht. Ich benutze es innerhalb der Schleife, um nur einzelne Div ohne innere Div darin auszudrucken.
Salem

Antworten:

769

empty() muss auf den Wert als Referenz zugreifen (um zu überprüfen, ob diese Referenz auf etwas verweist, das vorhanden ist), und PHP vor 5.5 unterstützte keine Verweise auf temporäre Werte, die von Funktionen zurückgegeben wurden.

Das eigentliche Problem, das Sie haben, ist jedoch, dass Sie es empty()überhaupt verwenden und fälschlicherweise glauben, dass sich der "leere" Wert von "falsch" unterscheidet.

Leer ist nur ein Alias ​​für !isset($thing) || !$thing. Wenn das, was Sie überprüfen, immer vorhanden ist (in PHP sind immer Ergebnisse von Funktionsaufrufen vorhanden), ist die empty()Funktion nichts anderes als ein Negationsoperator .

PHP hat kein Konzept von Leere . Werte, die als falsch ausgewertet werden, sind leer, Werte, die als wahr ausgewertet werden, sind nicht leer. Das ist gleich. Dieser Code:

$x = something();
if (empty($x)) 

und das:

$x = something();
if (!$x) 

hat in allen Fällen für alle Datentypen immer das gleiche Ergebnis (da $xdefiniert empty()redundant ist).

Der Rückgabewert der Methode ist immer vorhanden (auch wenn Sie keine returnAnweisung haben, ist der Rückgabewert vorhanden und enthält null). Deshalb:

if (!empty($r->getError()))

ist logisch äquivalent zu:

if ($r->getError())
Kornel
quelle
29
Dies ist eine viel bessere Antwort als die derzeit ausgewählte.
SystemParadox
20
@gcb: nein, das PHP-Handbuch sagt ausdrücklich, dass es identisch ist: "empty () ist das Gegenteil von (boolean) var, außer dass keine Warnung generiert wird, wenn die Variable nicht gesetzt ist."
Kornel
16
Das Nicht-Generieren eines Warnungsteils ist ziemlich wichtig ... leer ($ var) gibt true zurück, wenn es 0, '', array (), NULL oder nicht einmal definiert ist. Es ist eine gute Praxis, vor allem, damit Sie Ihre echten Warnungen protokollieren können, ohne dass sich die Dateien füllen
Landons
3
Ok, tolle Antwort, aber was ist der richtige Weg, um dies zu vermeiden, weiß jemand?
Javatar
3
@EugenMihailescu im Allgemeinen , das ist in Ordnung, aber es ist nicht absolut gleichwertig () zu leeren, weil "", 0usw. „leer“ ist, aber nicht null.
Kornel
330

Hinweis: Dies ist eine sehr gut bewertete Antwort mit hoher Sichtbarkeit. Bitte beachten Sie jedoch, dass sie schlechte, unnötige Codierungspraktiken fördert! Siehe @ Kornels Antwort für den richtigen Weg.

Anmerkung 2: Ich unterstütze die Vorschläge, die Antwort von @ Kornel zu verwenden . Als ich diese Antwort vor drei Jahren schrieb, wollte ich lediglich die Art des Fehlers erklären und nicht unbedingt die Alternative unterstützen. Das folgende Code-Snippet wird nicht empfohlen.


Es ist eine Einschränkung von empty () in PHP-Versionen unter 5.5.

Hinweis: empty () überprüft nur Variablen, da alles andere zu einem Analysefehler führt. Mit anderen Worten, Folgendes funktioniert nicht: leer (trim ($ name)).

Das müsstest du ändern

// Not recommended, just illustrates the issue
$err = $r->getError();
if (!empty($err))
Peter Bailey
quelle
156
Das ist wahnsinnig kontraproduktiv.
David Murdoch
47
Hinweis: Gleiches gilt für isset(). dh: isset($this->foo->getBar())führt zum gleichen Problem.
catchdave
7
Die Antwort von porneL erklärt dies ausführlicher mit einer besseren Lösung
SystemParadox
5
@SystemParadox - Kommt darauf an, was du mit "besser" meinst. Die Antwort von porneL ist mit einer "saubereren" Lösung wohl gründlicher, erklärt aber auch nicht die Ursache des Fehlers.
Peter Bailey
4
Weil es nicht falsch ist, @deceze. Es ist nicht die beste Antwort, Sie werden dort kein Argument von mir bekommen. Ich habe sogar selbst PorneL's gewählt. Es ist eine sehr alte Antwort, aber es ist nicht falsch . In Bezug auf die hohen Stimmen: Denken Sie daran, dass PorneLs fast volle 17 Monate nach dieser eingetroffen sind.
Peter Bailey
37

Laut den PHP-Dokumenten :

empty () überprüft nur Variablen, da alles andere zu einem Analysefehler führt

Sie können empty()den Rückgabewert einer Funktion nicht direkt verwenden. Setzen Sie stattdessen die Rückgabe von getError()auf eine Variable und führen Sie sie empty()für die Variable aus.

George Claghorn
quelle
19

Normalerweise erstelle ich eine globale Funktion namens is_empty (), um dieses Problem zu umgehen

function is_empty($var)
{ 
 return empty($var);
}

Dann verwende ich überall dort, wo ich normalerweise leer () verwendet hätte, nur is_empty ()

Luke PM
quelle
2
Es ist besser, dies nicht zu tun und sich an die Standards zu halten (so ärgerlich sie auch sein mögen).
Tonyhb
1
@dynamism könntest du erklären warum nicht?
Janis Veinbergs
1
Weil Convenience-Funktionen das Einlesen des Codes einer anderen Person schwierig machen können. Außerdem kann es in einer MVC / HMVC-Architektur Ihre Struktur durcheinander bringen. Letztendlich sollten PHP-Codierer die Einschränkungen kennen und in der Lage sein, kleine Problemumgehungen ohne praktische Funktionen zu verstehen.
Tonyhb
14
Wow, du hast gerade eine Negationsfunktion erfunden . Sie wissen, dass PHP einen !Operator dafür hat? :)
Kornel
4

Wie von anderen betont, ist es eine (seltsame) Einschränkung von leer ().

Für die meisten Zwecke ist dies gleichbedeutend mit einem leeren Aufruf, aber dies funktioniert:

if ($r->getError() != '')
Jani Hartikainen
quelle
5
Dies ist nicht wahr - empty()deckt viel mehr Möglichkeiten als nur eine leere Zeichenfolge
Robbie Averill
3
Deshalb heißt es "für die meisten Zwecke ", nicht für alle
Jani Hartikainen
2

Das Problem ist, dass Sie wissen möchten, ob der Fehler nicht leer ist.

public function getError() {
    return $this->error;
}

Das Hinzufügen einer Methode isErrorSet () löst das Problem.

public function isErrorSet() {
    if (isset($this->error) && !empty($this->error)) {
        return true;
    } else {
        return false;
    }
}

Jetzt funktioniert dies mit diesem Code ohne Vorankündigung.

if (!($x->isErrorSet())) {
    echo $x->getError();
}
Jean Carlo Bambalan
quelle
-3

Die alternative Methode zum Überprüfen, ob ein Array leer ist, könnte sein:

count($array)>0

Es funktioniert bei mir ohne diesen Fehler

Quardas
quelle