$item['price'] = 0;
/* Code to get item information goes in here */
if($item['price'] == 'e') {
$item['price'] = -1;
}
Es ist beabsichtigt, den Artikelpreis auf 0 zu initialisieren und dann Informationen darüber zu erhalten. Wenn der Preis als „e“ angegeben wird, bedeutet dies einen Tausch anstelle eines Verkaufs, der als negative Zahl in einer Datenbank gespeichert wird.
Es besteht auch die Möglichkeit, den Preis auf 0 zu belassen, entweder weil der Artikel ein Bonus ist oder weil der Preis zu einem späteren Zeitpunkt festgelegt wird.
Aber immer wenn der Preis nicht festgelegt ist, was ihn mit dem Anfangswert von 0 belässt, wird die if Die oben angegebene Schleife wird als wahr ausgewertet und der Preis wird auf -1 gesetzt. Das heißt, es betrachtet 0 als gleich ‘e’.
Wie lässt sich das erklären?
Wenn der Preis als 0 angegeben wird (nach der Initialisierung), ist das Verhalten unberechenbar: manchmal wird if als wahr ausgewertet, manchmal als falsch.*
Ich habe festgestellt, dass die Verwendung von triple === anstelle von double == das erwartete Verhalten ergibt. Aber es ist trotzdem seltsam.
Wenn der einzig mögliche Zeichenfolgentyp „e“ ist, können Sie nicht einfach eine is_string($item[“price”]) prüfen? Das wäre etwas effizienter als ===. [citation needed]
– Jimmie Lin
27. Juli 2011 um 11:54 Uhr
in schwache Vergleiche zwischen String und Integer Die Zeichenfolge wird in eine Ganzzahl konvertiert (anstatt dass die Ganzzahl in eine Zeichenfolge “befördert” wird). if((string)$item['price'] == 'e') behebt das seltsame Verhalten. Siehe stackoverflow.com/a/48912540/1579327 für mehr Details
– Paulo
21. Februar 2018 um 18:08 Uhr
Bitte beachten Sie einen weiteren Fall in den Kommentaren unten von @Paolo, bei dem 0 (Ganzzahl) bei Verwendung des Double-Equals-Operators gleich jeder anderen Zeichenfolge ist.
– Haitham Sweilem
24. Juni 2018 um 16:30 Uhr
Nanne
Du machst == die die Typen für Sie aussortiert.
0 ist ein int, also wird es in diesem Fall gecastet 'e' zu einem int. Was nicht als eins parsbar ist und werden wird 0. Ein Faden '0e' würde werden 0 und würde passen!
Vergleiche zwischen Zeichenfolgen und Zahlen mit == und anderen nicht strengen Vergleichsoperatoren funktionieren derzeit, indem die Zeichenfolge in eine Zahl umgewandelt wird und anschließend ein Vergleich mit Ganzzahlen oder Gleitkommazahlen durchgeführt wird. Dies führt zu vielen überraschenden Vergleichsergebnissen, von denen das bemerkenswerteste ist, dass 0 == “foobar” wahr zurückgibt.
Beim Vergleich mit einer numerischen Zeichenfolge verwendet PHP 8 einen Zahlenvergleich. Andernfalls konvertiert es die Zahl in eine Zeichenfolge und verwendet einen Zeichenfolgenvergleich.
PHP7
0 == 'foobar' // true
0 == '' // true
4 == '4e' // true (4e is cast as a number and becomes 4)
PHP 8 wandelt Zahlen in Strings um, bevor Vergleiche durchgeführt werden
0 == 'foobar' // false
0 == '' // false
4 == '4e' // false ('4e' is considered non-numeric therefore 4 is cast as a string and becomes '4')
Dies ist eine große Änderung, daher wurde sie in einer neuen Haupt-PHP-Version implementiert. Diese Änderung unterbricht die Abwärtskompatibilität in Skripten, die vom alten Verhalten abhängen.
Ein weiterer Nachteil des lockeren Vergleichs.
– MC Kaiser
5. Oktober 2014 um 13:46 Uhr
Knifflig. Ich bin gerade auf dieses hier gestoßen und war erstaunt, warum Zeichenfolge == 0. Daran muss ich mich erinnern.
– Grzegorz
28. September 2016 um 17:42 Uhr
Kratzte mich auch an diesem Kopf, als ich String-Schlüssel durchschleifte, aber das Array hatte ein anfängliches Indexelement „Null“, das beim Vergleich des ersten String-Schlüssels immer wahr blieb. Ich war wie was? Wie um alles in der Welt hat diese Antwort das klargestellt! Ich bin überrascht, dass diese ganze Frage nicht EINE akzeptierte Antwort hat. Das zeigt nur, dass einige Fragesteller Idioten sind.
– Unglaublicher Hut
23. März 2018 um 21:04 Uhr
Dies liegt daran, wie PHP die Vergleichsoperation durchführt, die die == Vergleichsoperator bezeichnet:
Wenn Sie eine Zahl mit einer Zeichenkette vergleichen oder der Vergleich numerische Zeichenketten umfasst, wird jede Zeichenkette in eine Zahl umgewandelt und der Vergleich numerisch durchgeführt. […] Die Typkonvertierung findet nicht statt, wenn der Vergleich erfolgt === oder !== da dabei sowohl der Typ als auch der Wert verglichen werden.
Wenn eine Zeichenfolge in einem numerischen Kontext ausgewertet wird, werden der resultierende Wert und Typ wie folgt bestimmt.
Wenn die Zeichenfolge keines der Zeichen ‘.‘, ‘e‘, oder ‘E‘ und der numerische Wert passt in die Grenzen von Integer-Typen (wie definiert durch PHP_INT_MAX), wird die Zeichenfolge als Ganzzahl ausgewertet. In allen anderen Fällen wird es als Float ausgewertet.
In diesem Fall ist die Zeichenfolge 'e' und wird daher als Float ausgewertet:
Der Wert wird durch den Anfangsteil der Zeichenfolge angegeben. Wenn die Zeichenfolge mit gültigen numerischen Daten beginnt, ist dies der verwendete Wert. Andernfalls wird der Wert sein 0 (Null). Gültige numerische Daten sind ein optionales Vorzeichen, gefolgt von einer oder mehreren Ziffern (die optional einen Dezimalpunkt enthalten), gefolgt von einem optionalen Exponenten. Der Exponent ist ein ‘e‘ oder ‘E‘ gefolgt von einer oder mehreren Ziffern.
Als 'e' nicht mit gültigen numerischen Daten beginnt, wird es als Float ausgewertet 0.
php gestaltet fast alles so, dass es leicht vergleichbar ist, und wirft dann ein paar Fallstricke ein, nur um unseren Tag zu ruinieren. Dies passt nicht zur übrigen Designphilosophie von PHP. Wenn es keine Täuschung gibt, gibt es eine Philosophie???
– Benutzer3338098
30. Juli 2015 um 15:38 Uhr
zumal “e” auf true und “” auf false umwandelt
– Benutzer3338098
19. August 2015 um 21:15 Uhr
Paolo
"ABC" == 0
bewertet true da Erste"ABC" wird in eine Ganzzahl umgewandelt und wird 0dann es wird verglichen mit 0.
Das ist ein seltsam Verhalten der PHP-Sprache: normalerweise würde man erwarten 0 zum String befördert werden "0" und dann verglichen mit "ABC" mit einem Ergebnis false. Vielleicht passiert das in anderen Sprachen wie JavaScript, wo der schwache Vergleich "ABC" == 0 bewertet false.
Ein strenger Vergleich löst das Problem:
"ABC" === 0
bewertet false.
Aber Was ist, wenn ich Zahlen als Zeichenfolgen mit Zahlen vergleichen muss?
"123" === 123
bewertet false weil linker und rechter Term von unterschiedlichem Typ sind.
Was tatsächlich benötigt wird, ist ein schwacher Vergleich ohne die Fallstricke des Jonglierens von PHP-Typen.
Die Lösung besteht darin, die Terme explizit zu Strings hochzustufen und dann einen Vergleich durchzuführen (streng oder schwach spielt keine Rolle mehr).
(string)"123" === (string)123
ist
true
während
(string)"123" === (string)0
ist
false
Auf den Originalcode angewendet:
$item['price'] = 0;
/*code to get item information goes in here*/
if((string)$item['price'] == 'e') {
$item['price'] = -1;
}
Vincent Mimoun-Prat
Der Operator == versucht, Werte abzugleichen, auch wenn sie unterschiedlichen Typs sind. Zum Beispiel:
'0' == 0 will be true
Wenn Sie auch einen Typvergleich benötigen, verwenden Sie den Operator ===:
'0' === 0 will be false
Sebastian Renauld
Ihr Problem ist der doppelte Gleichheitsoperator, der das rechte Mitglied in den Typ des linken umwandelt. Verwenden Sie strict, wenn Sie dies vorziehen.
Kommen wir zurück zu Ihrem Code (oben kopiert). In diesem Fall in den meisten Fällen $item[‘price’] eine Ganzzahl ist (außer natürlich, wenn sie gleich e ist). Als solches wird PHP nach den Gesetzen von PHP typisieren "e" zu Integer, was ergibt int(0). (Glaubst du mir nicht? <?php $i="e"; echo (int)$i; ?>).
Um dies einfach zu umgehen, verwenden Sie den Triple-Equal-Operator (exakter Vergleich), der den Typ überprüft und nicht implizit typisiert.
PS: ein PHP Fun Fact: a == b bedeutet das nicht b == a. Nehmen Sie Ihr Beispiel und kehren Sie es um: if ("e" == $item['price']) wird niemals tatsächlich erfüllt, vorausgesetzt, dass $item[‘price’] ist immer eine ganze Zahl.
Jim Morrison
Es gibt eine ziemlich praktische Methode in PHP, um eine Mischung aus “0”, “false”, “off” als == false und “1”, “on”, “true” als == true zu validieren, was oft übersehen wird. Es ist besonders nützlich zum Analysieren von GET/POST-Argumenten:
Es ist für diesen Anwendungsfall nicht ganz relevant, aber angesichts der Ähnlichkeit und Tatsache, dass dies das Ergebnis der Suche ist, das tendenziell gefunden wird, wenn die Frage gestellt wird, ob (String) “0” als falsch validiert werden soll, dachte ich, es würde anderen helfen.
Ich habe festgestellt, dass die Verwendung von triple === anstelle von double == das erwartete Verhalten ergibt. Aber es ist trotzdem seltsam.
– Sergio Domingues
27. Juli 2011 um 10:46 Uhr
(Hinweis) ausreichend erklärt im PHP-Handbuch im Kapitel Geben Sie Jonglieren ein und abgebildet in der Typenvergleichstabelle
– Gordon
27. Juli 2011 um 10:56 Uhr
Wenn der einzig mögliche Zeichenfolgentyp „e“ ist, können Sie nicht einfach eine is_string($item[“price”]) prüfen? Das wäre etwas effizienter als ===. [citation needed]
– Jimmie Lin
27. Juli 2011 um 11:54 Uhr
in schwache Vergleiche zwischen String und Integer Die Zeichenfolge wird in eine Ganzzahl konvertiert (anstatt dass die Ganzzahl in eine Zeichenfolge “befördert” wird).
if((string)$item['price'] == 'e')
behebt das seltsame Verhalten. Siehe stackoverflow.com/a/48912540/1579327 für mehr Details– Paulo
21. Februar 2018 um 18:08 Uhr
Bitte beachten Sie einen weiteren Fall in den Kommentaren unten von @Paolo, bei dem 0 (Ganzzahl) bei Verwendung des Double-Equals-Operators gleich jeder anderen Zeichenfolge ist.
– Haitham Sweilem
24. Juni 2018 um 16:30 Uhr