Ich habe den folgenden Code:
$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 Umtausch anstelle eines Verkaufs, der als negative Zahl in einer Datenbank gespeichert wird.
Es besteht auch die Möglichkeit, den Preis als 0 zu belassen, entweder weil der Artikel ein Bonus ist oder weil der Preis zu einem späteren Zeitpunkt festgelegt wird.
Wenn jedoch der Preis nicht festgelegt ist und der Anfangswert 0 bleibt, wird die if
oben angegebene Schleife als wahr ausgewertet und der Preis auf -1 festgelegt. Das heißt, es betrachtet 0 als gleich 'e'.
Wie kann das erklärt werden?
Wenn der Preis als 0 angegeben wird (nach der Initialisierung), ist das Verhalten unberechenbar: Manchmal wird das if als wahr bewertet, manchmal als falsch. *
if((string)$item['price'] == 'e')
behebt das seltsame Verhalten. Siehe stackoverflow.com/a/48912540/1579327 für weitere DetailsAntworten:
Sie tun,
==
was die Typen für Sie aussortiert.0
ist ein int, also wird es in diesem Fall'e'
in ein int umgewandelt. Welches ist nicht als eins analysierbar und wird werden0
. Eine Saite'0e'
würde werden0
und passen!Verwenden
===
quelle
Dies liegt daran, wie PHP die vom Vergleichsoperator angegebene
==
Vergleichsoperation ausführt:Da der erste Operand eine Zahl (
0
) und der zweite eine Zeichenfolge ('e'
) ist, wird die Zeichenfolge ebenfalls in eine Zahl konvertiert (siehe auch Tabelle Vergleich mit verschiedenen Typen ). Auf der Handbuchseite zum Datentyp der Zeichenfolge wurde definiert, wie die Konvertierung von Zeichenfolgen in Zahlen durchgeführt wird:In diesem Fall ist der String
'e'
und wird daher als float ausgewertet:Da
'e'
es nicht mit gültigen numerischen Daten beginnt, wird es als float ausgewertet0
.quelle
wird ausgewertet,
true
weil zuerst"ABC"
in eine Ganzzahl konvertiert wird und0
dann wird es mit verglichen0
.Dies ist ein merkwürdiges Verhalten der PHP-Sprache: Normalerweise würde man erwarten
0
, zum String befördert zu werden"0"
und dann"ABC"
mit einem Ergebnis verglichen zu werdenfalse
. Vielleicht passiert das in anderen Sprachen wie JavaScript, wo der schwache Vergleich"ABC" == 0
ausgewertet wirdfalse
.Ein strenger Vergleich löst das Problem:
bewertet
false
.Aber was ist, wenn ich Zahlen als Zeichenfolgen mit Zahlen vergleichen muss?
bewertet
false
weil der linke und der rechte Begriff vom unterschiedlichen Typ sind.Was tatsächlich benötigt wird, ist ein schwacher Vergleich ohne die Fallstricke des PHP-Jonglierens.
Die Lösung besteht darin, die Begriffe explizit auf String zu setzen und dann einen Vergleich durchzuführen (streng oder schwach spielt keine Rolle mehr).
ist
true
während
ist
false
Auf den Originalcode angewendet:
quelle
Der Operator == versucht, Werte abzugleichen, auch wenn sie unterschiedlichen Typs sind. Zum Beispiel:
Wenn Sie auch einen Typvergleich benötigen, verwenden Sie den Operator ===:
quelle
Ihr Problem ist der Double-Equal-Operator, der das rechte Element in den Typ des linken Typs umwandelt. Verwenden Sie streng, wenn Sie es vorziehen.
Kehren wir zu Ihrem Code zurück (oben kopiert). In diesem Fall ist $ item ['price'] in den meisten Fällen eine Ganzzahl (außer wenn sie offensichtlich gleich e ist). Nach den Gesetzen von PHP wird PHP als
"e"
Ganzzahl typisiert , was ergibtint(0)
. (Glaubst du mir nicht?<?php $i="e"; echo (int)$i; ?>
)Verwenden Sie den Operator Triple Equal (exakter Vergleich), der den Typ überprüft und nicht implizit typisiert, um dies zu vermeiden.
PS: eine lustige PHP-Tatsache:
a == b
impliziert das nichtb == a
. Nehmen Sie Ihr Beispiel und kehren Sie es um:if ("e" == $item['price'])
wird niemals tatsächlich erfüllt, vorausgesetzt, $ item ['price'] ist immer eine ganze Zahl.quelle
In PHP gibt es eine ziemlich praktische Methode, um eine Mischung aus "0", "false", "off" als == false und "1", "on", "true" als == true zu validieren, die oft übersehen wird. Dies ist besonders nützlich, um GET / POST-Argumente zu analysieren:
Es ist nicht ganz relevant für diesen Anwendungsfall, aber angesichts der Ähnlichkeit und Tatsache, dass dies das Ergebnis ist, das die Suche häufig findet, wenn die Frage nach der Validierung (Zeichenfolge) "0" als falsch gestellt wird, dachte ich, es würde anderen helfen.
http://www.php.net/manual/en/filter.filters.validate.php
quelle
Sie sollten
===
anstelle von verwenden==
, da der normale Operator die Typen nicht vergleicht. Stattdessen wird versucht, die Elemente zu typisieren.In der Zwischenzeit
===
berücksichtigt die Art der Artikel.===
bedeutet "gleich",==
bedeutet "eeeeh .. sieht irgendwie aus wie"quelle
if((string)$item['price']=='e'){ $item['price'] = -1; }
===
OperatorIch denke, es ist am besten, anhand von Beispielen zu zeigen, die ich gemacht habe, während ich auf dasselbe seltsame Verhalten stoße. Sehen Sie sich meinen Testfall an und hoffentlich hilft er Ihnen dabei, das Verhalten besser zu verstehen:
quelle
Verwenden Sie grundsätzlich immer den
===
Bediener, um die Typensicherheit zu gewährleisten.quelle