2009-03-23 10 views
26

Ich bin wirklich verwirrt, warum diese Operation funktioniert. Kann es jemand erklären?Vergleichen von String zu Integer gibt seltsame Ergebnisse

$test1 = "d85d1d81b25614a3504a3d5601a9cb2e"; 
$test2 = "3581169b064f71be1630b321d3ca318f"; 

if ($test1 == 0) 
    echo "Test 1 is Equal!?"; 
if ($test2 == 0) 
    echo "Test 2 is Equal!?"; 

// Returns: Test 1 is Equal!? 

Zur Klarstellung Ich versuche, die Zeichenfolge "0" die $test Variablen zu vergleichen. Ich weiß bereits, um den Code zu beheben, den ich (wie ich sollte) einfach die 0 in "" s

Ich frage mich, ob dies ein PHP-Fehler ist, ein Server-Fehler oder irgendwie eine gültige Operation. Nach http://us3.php.net/types.comparisons sollte diese nicht haben gearbeitet.

Bearbeiten: Scratch, dass es offensichtlich erwähnt, dass Lose Vergleiche zwischen Zeichenfolge und 0 ist wahr. Aber ich weiß immer noch nicht warum.

Bearbeiten 2: Ich habe meine Frage überarbeitet, warum funktioniert der $test2 Wert von "3581169b064f71be1630b321d3ca318f" nicht?

+0

welcher $ Testwert funktioniert nicht? –

+0

Wenn Sie den Code ausführen, gibt es nur aus: Test 1 ist gleich!? –

+0

echo (int) $ test2; – OIS

Antwort

28

From the PHP manual:

String Umwandlung in Zahlen

Wenn eine Zeichenfolge in einem numerischen Kontext beurteilt wird, wird der resultierende Wert und Typ wie folgt bestimmt.

Der String wird als float ausgewertet, wenn er eines der Zeichen ".", "E" oder "E" enthält. Andernfalls wird es als Integer ausgewertet.

Der Wert wird durch den ursprünglichen -Teil der Zeichenfolge angegeben. Wenn die Zeichenfolge mit gültigen numerischen Daten beginnt, wird als Wert verwendet. Andernfalls wird der Wert 0 (Null) sein. Gültige numerische Daten sind ein optionales Zeichen, gefolgt von eine oder mehrere Ziffern (optional enthält einen Dezimalpunkt), gefolgt durch einen optionalen Exponenten. Der Exponent ist ein 'e' oder 'E' gefolgt von einem oder mehr Ziffern.

+0

Noch nicht denken, dass es in eine 0 konvertieren sollte, oder zumindest, wenn es mit einer Zahl beginnt, nicht in eine Dezimalzahl zu konvertieren, wenn in der Zeichenfolge fehlerhafte Zeichen vorliegen. –

+2

PHP hat keinen "NaN" -Typ wie Javascript (eine andere lose-typisierte Sprache), also muss es ziemlich viel in 0 umgewandelt werden, da es keinen anderen Weg gäbe (die Konvertierung zu NULL würde nicht funktionieren, cos NULL konvertiert auch zu 0). Ich denke, die Antwort besteht nicht darin, einen losen Vergleich (==) zu verwenden, oder die Zeichenfolge zuerst zu validieren. – thomasrutter

+1

** Zusätzlich zu dieser Antwort ** wird beim Vergleich von 2 Elementen mit dem Operator == 'in den allgemeinen Typ konvertiert. es wird hier erwähnt. http://www.php.net/manual/en/language.operators.comparison.php – Nis

9

Typumwandlung des Operator ==

Der Operator == ist ein lose typisierte Vergleich verwendet wird. Es konvertiert beide in einen gemeinsamen Typ und vergleicht sie. Die Art und Weise, wie Strings in Ganzzahlen konvertiert werden, ist explained here. Bitte beachten Sie, dass die page you linked to dem nicht widerspricht. Überprüfen Sie die zweite Tabelle, in der steht, dass der Vergleich der Ganzzahl 0 mit einer Zeichenkette "php" unter Verwendung von == zutrifft.

Was passiert ist, dass die Zeichenfolge in Ganzzahl konvertiert wird, und nicht numerische Zeichenfolgen (Zeichenfolgen, die nicht oder beginnen mit einer Zahl) konvertieren in 0.

Numeric vs nicht-numerischen Strings

Eine Zeichenfolge, die aus einer Reihe besteht, oder mit einer Zahl beginnt, gilt als Ziffernfolge. Wenn die Zeichenfolge nach dieser Nummer andere Zeichen enthält, werden diese ignoriert.

Wenn eine Zeichenfolge mit einem Zeichen beginnt, die nicht als Teil einer Zahl interpretiert werden kann, dann ist es eine nicht-numerische Zeichenfolge und wird 0 konvertieren. Dies bedeutet nicht, dass ein numerischer String mit einer Ziffer (0-9) beginnen muss - zum Beispiel ist "-1" ein numerischer String, weil das Minuszeichen in diesem Fall Teil einer Zahl ist.

So zum Beispiel beginnt Ihre Zeichenfolge "d85d1d81b25614a3504a3d5601a9cb2e" nicht mit einer Zahl, so würde es in 0 konvertieren. Aber Ihre zweite Zeichenfolge "3581169b064f71be1630b321d3ca318f" würde in Ganzzahl 3581169 konvertiert werden. Deshalb funktioniert dein zweiter Test nicht auf die gleiche Weise.

Was sollten Sie tun

Sie wollen wahrscheinlich:

if ($test1 === "0") 

Beachten Sie die Verwendung von Triple-Gleichen statt eines Doppel Gleichen.Dies stellt sicher, dass das, was Sie vergleichen, eine Zeichenfolge ist, die nur die Ziffer Null enthält und jegliche Typumwandlung verhindert.

6

Nach einigen Untersuchungen stellt sich heraus, dass Aidan aus dem PHP-Handbuch erwähnt, dass alle Zeichenfolgen, die nicht mit einer Nummer beginnen, in 0 umgewandelt werden, wenn sie als Ganzzahl ausgegeben werden. Diese

bedeutet:

("php" == 0) === true 
("1php" == 0) === false 

Sehr ärgerlich und nicht gut dokumentiert. Es war am Ende der Kommentare auf der Typenvergleichsseite.

+1

Ja, dachte, das war es. Schlechte Dokumentation in der Tat. –

+0

Ich glaube nicht, dass es überhaupt eine schlechte Dokumentation ist. Implizite Typkonvertierung ist eine Grundvoraussetzung von PHP, die im Handbuch im Abschnitt Typen, insbesondere im Abschnitt Typ-Juggling, sehr gut erklärt wird. == ist ein locker typisierter Vergleich; Mit === können Sie verwirrende Situationen vermeiden. – thomasrutter

+0

Siehe auch "String-Konvertierung zu Zahlen" unter http://us3.php.net/manual/en/language.types.string.php#language.types.string.Umwandlung – thomasrutter

1

Ich habe einige Umbauten und Vergleiche wurden unter Verwendung zu testen, ob eine numerische Zeichenfolge eine Zahl:

$test1="19de6a91d2ca9d91721d82f1bd8102b6"; 
    echo (float)$test1==$test1; //TRUE 
    echo is_float($test1); //FALSE 

    //Converting the string to float and then converting it to string and compare will do the trick 
    echo (string)((float)$test1)==(string)$test1; //FALSE 


$test2="5.66"; 
    echo (float)$test2==$test2; //TRUE 

    //Testing the numeric string using `is_float` wont give the expected result 
    echo is_float($test2); //FALSE 

    echo (string)((float)$test2)==(string)$test2; //TRUE 
2
$test1 = "d85d1d81b25614a3504a3d5601a9cb2e"; 

diese Zeichenfolge beginnt mit einem „d“, die nicht gültig ist Nummer wird die Variable auf 0 aufgelöst und Ihr Test # 1 wird bestanden.

$test2 = "3581169b064f71be1630b321d3ca318f"; 

diese Zeichenfolge beginnt mit 3.581.169, die eine gültige Zahl ist, so dass die var auf diesen Wert aufgelöst wird, die nicht gleich 0. Also Ihr Test # 2 wird nicht passieren.

Verwandte Themen