Warum behandelt PHP "0" in booleschen Kontexten als FALSCH?

12

"0" als Zeichenfolge mit einem Zeichen ist intuitiv nicht leer. Warum behandelt PHP es im Gegensatz zu anderen Programmiersprachen als FALSCH, wenn es in einen Booleschen Wert konvertiert wird?

Michael Tsang
quelle
2
Duplikat von: stackoverflow.com/questions/523643/… . Es ist dasselbe in PHP und Javascript. Überprüfe die Antwort unter der akzeptierten Antwort.
Walfrat
5
Das liegt daran, dass PHP große Anstrengungen unternimmt, um sowohl mit sich selbst als auch mit jeder anderen Programmiersprache so inkonsistent wie möglich zu sein.
David Arno
2
@DavidArno Im Gegenteil, es tut sein Bestes, um konsequent zu sein . Sobald Sie mit dem Autocasting von Zeichenfolgen beginnen (sehr praktisch in einer Sprache, in der häufig Variablen von URLs oder Anforderungskörpern abgerufen werden), müssen Sie diese Logik befolgen. Wenn '0'wie 0in behandelt wird $x + 1, warum sollte es nicht auch wie 0und daher wie falsein behandelt werden if ( $x )?
IMSoP
1
@ DavidArno genau;)
Linuxunil
1
@DavidArno Sobald Sie anfangen, verlustbehaftete Casts auszuführen, ist meiner Meinung nach eine gewisse Inkonsistenz unvermeidlich. Die konsequente Lösung besteht darin, einige Abgüsse abzulehnen und den Rest sehr sorgfältig zu gestalten. Sehr wenige populäre Sprachen werden jedoch von Grund auf neu entwickelt. Die meisten ergeben sich entweder aus zufälligen Experimenten oder aus älteren Sprachen mit unterschiedlichen Zielen und Gepäck. Sogar C #, das eine Menge fundamentalen theoretischen Designs hat, hat ein Vermächtnis von C, das niemals so universell sein sollte, wie es wurde. Snark mag "sich sehr bemühen, inkonsistent zu sein", ist wie den Schiedsrichter bei einem Sportmatch anzuschreien.
IMSoP

Antworten:

12

PHP wurde für die Verwendung mit Webanforderungen entwickelt (oder vielmehr weiterentwickelt), bei denen Sie häufig mit Zeichenfolgeneingaben (URL-Parametern oder POST-Anforderungen aus einem Formular in einem Browser) arbeiten. Daher werden Zeichenfolgen automatisch in andere Typen umgewandelt.

Ein einfaches Beispiel hierfür ist, dass '1' + '2'es 3keinen Fehler gibt, oder '12', oder eine andere Interpretation. Nach der gleichen Logik kann die Zeichenfolge '0'als Zahl verwendet werden 0.

Unterdessen behandelt PHP wie viele andere Sprachen bestimmte Werte als "falsch", wenn sie in boolesche Werte umgewandelt werden - solche, die, wie Sie sagen, intuitiv "leer" sind. Dazu gehören numerische Zeichen 0sowie die leere Zeichenfolge ''und das leere Array []. In einer ifErklärung, wird der Ausdruck explizit auf boolean werfen, so if ( 0 )ist das gleiche wie if ( false ).

Wenn Sie diese beiden Dinge zusammenfassen, bekommen Sie ein Rätsel: Einerseits, wie Sie sagen, '0'handelt es sich um eine nicht leere Zeichenfolge; Auf der anderen Seite haben wir gesagt, dass es als eine Zahl verwendet werden kann 0, die "leer" ist. PHP entscheidet sich dafür, die "Null" als wichtiger als die '0'"Stringiness" zu behandeln, so dass dies als "falsch" betrachtet wird.

Kurz gesagt '0' == 0 == false:; oder(bool)'0' === (bool)(int)'0'

IMSoP
quelle
Hat jemand meine Antwort abgelehnt, nur weil ich es gewagt habe, PHP zu verteidigen und die Frage mit etwas anderem als einem billigen und ignoranten Witz zu beantworten? Oder gibt es in meiner Antwort etwas Unrichtiges oder Nicht-Nützliches, worauf sie hinweisen möchten?
IMSoP
1
Ich denke, PHP hat dies von Perl übernommen, das das gleiche „ "0" falsche“ Verhalten hat. In Perl gibt es buchstäblich keinen vom Benutzer sichtbaren Unterschied zwischen der Zeichenfolge "0"und der Zahl 0- ärgerlich beim Umgang mit JSON, aber sehr intuitiv beim Umgang mit Textdaten. Es ist dann unmöglich, dass die Zahl 0falsch ist, ohne dass auch die Zeichenfolge "0"falsch ist. PHP und JavaScript leihen diese Design - Entscheidung, sondern eine gewisse Verwirrung durch die Unterscheidung strings / bools / numerische Typen , während immer noch implizite Konvertierungen ermöglichen (PHP: 0 == "0 foo", 0 == false, aber "0 foo" == true: ==ist transitiv nicht)
amon
@amon Ja, Perl nutzt den interessanten Ansatz (fast) aller Operatoren und integrierten Funktionen, um Operanden zu einem bestimmten Typ zu zwingen, mit zusätzlichen Operatoren wie der eqZeichenfolgengleichheit. Dies rettet es jedoch nicht vor der Nicht-Transitivität verlustbehafteter Casts: "0 foo"Ist im booleschen Kontext wahr, aber gleich 0unter ==. Also if ( ! $foo ) ..und $false = (1 == 2); if ( $foo == $false ) ... gib nicht das gleiche Ergebnis. Ich vermute, der Sprache fehlt ein "Boolean Equality" -Operator, der dies konsequent behandeln könnte ...
IMSoP
Obwohl "0" 0 ist, wenn es als numerisch ausgewertet wird, interessieren wir uns nicht für seinen numerischen Wert, wenn wir einen String in einem booleschen Kontext verwenden (z. B. in einer if-Anweisung). Wenn wir es als numerisch interpretieren möchten, würden wir es beispielsweise mit einer Zahl vergleichen $_POST['id'] == 0, was die Absicht verdeutlicht, dass wir die Benutzereingabe als Zahl behandeln möchten.
Michael Tsang
1
@MestreLion Dieses Beispiel war eher von Perl als von PHP. Der entscheidende Unterschied besteht darin , dass es keinen separaten booleschen Typ in Perl, so $falseendet Satz 0; Wenn Sie also schreiben $foo == $false, weiß Perl nicht, dass Sie einen booleschen Vergleich wünschen, und wandelt stattdessen in int um. In PHP passiert das nicht, weil $falseboolean false ist, also wird es ==in boolean umgewandelt und ergibt dasselbe Ergebnis wie!
IMSoP
3

Laut der PHP-Dokumentation zu Booleans heißt es:

Bei der Konvertierung in einen Booleschen Wert werden die folgenden Werte berücksichtigt FALSE
:
die leere Zeichenfolge und die Zeichenfolge "0"
.

Andernfalls:

Jeder andere Wert wird als WAHR betrachtet (einschließlich aller Ressourcen).

Wenn du läufst:

var_dump((bool) "0");

Es wird gedruckt:

bool (falsch)

Es funktioniert also wie erwartet.


So beantworten Sie Ihre Frage explizit:

In den meisten Fällen ist die Umwandlung jedoch nicht erforderlich, da ein Wert automatisch konvertiert wird, wenn ein Operator, eine Funktion oder eine Steuerelementstruktur ein boolesches Argument erfordert.

Dies bedeutet, dass PHPs "Autocast" "0" in Ganzzahl 0 umwandelt, was FALSEauch in einer Kontrollstruktur wie etwa einer if()Anweisung der Fall ist .

Kayess
quelle
Ich würde gerne wissen, warum die Entwurfsentscheidung "0" als FALSCH behandelt, wenn sie in einen Booleschen Wert konvertiert wird, und nicht, dass explizites Casting erforderlich ist.
Michael Tsang