15 Stimmen

Ein Problem mit in_array

Ich habe kürzlich ein seltsames Problem mit in_array bekommen, das ich nicht verstehen kann. z.B.

$a = array('a','b','c');
$b = array(1,2,3);

if (in_array(0,$a))
{
    echo "a bingo!\n";
}
else
{
    echo "a miss!\n";
}

if (in_array(0,$b))
{
    echo "b bingo!\n";
}
else
{
    echo "b miss!\n";
}

Ich habe es auf meinem LAMP ausgeführt und bekam

a bingo!
b miss!

Ich habe das Handbuch gelesen und den dritten Parameter $strict als true gesetzt, dann hat es wie erwartet funktioniert. Aber bedeutet das, dass ich den strict-Parameter immer auf true setzen muss, wenn ich in_array benutze? Vorschläge wären willkommen.

Mit freundlichen Grüßen

20voto

Pascal MARTIN Punkte 384469

Das bedeutet, dass Sie den dritten Parameter auf true setzen müssen, wenn Sie möchten, dass der Vergleich nicht nur Werte, sondern auch Typen vergleicht.

Andernfalls kommt es zu Typumwandlungen, während die Vergleiche durchgeführt werden - siehe z.B. String-Umwandlung in Zahlen.

Tatsächlich ist in_array ohne und mit strict nur der gleiche Unterschied wie zwischen == und === - siehe Vergleichsoperatoren.

Diese Umwandlung funktioniert die meiste Zeit gut... Aber nicht, wenn Sie versuchen, 0 mit einem String zu vergleichen, der mit einem Buchstaben beginnt: Der String wird in eine Zahl umgewandelt, die den Wert 0 hat.

6voto

Gumbo Punkte 617646

Der „Standard“-Modus von in_array verwendet eine lockere Vergleichsmethode, ähnlich wie der == Vergleichsoperator es tut. Das bedeutet, dass 0 wie folgt verglichen wird:

var_dump(0 == 'a');  // bool(true)
var_dump(0 == 'b');  // bool(true)
var_dump(0 == 'c');  // bool(true)

Der lockere Vergleichsoperator == verwendet eine Konvertierung von Strings zu Integer bevor die Werte tatsächlich verglichen werden:

Wenn Sie eine Zahl mit einem String vergleichen oder der Vergleich numerische Strings involviert, dann wird jeder String in eine Zahl umgewandelt und der Vergleich numerisch durchgeführt.

Und 'a', 'b' und 'c' werden alle zu 0 konvertiert:

var_dump((int) 'a');  // int(0)
var_dump((int) 'b');  // int(0)
var_dump((int) 'b');  // int(0)

Aber wenn Sie in_array im strict Modus verwenden (setzen Sie den dritten Parameter auf true), wird ein strenger Vergleich (===) durchgeführt, das bedeutet, dass sowohl der Wert als auch der Typ gleich sein müssen:

var_dump(0 === 'a');  // bool(false)
var_dump(0 === 'b');  // bool(false)
var_dump(0 === 'c');  // bool(false)

Also, wenn Sie in_array im strict Modus verwenden, erhalten Sie das erwartete Ergebnis:

var_dump(in_array(0, $a, true));  // bool(false)

1voto

David V. Punkte 5615

In Ihrem ersten Beispiel ist jeder Wert des Arrays $a, wenn er in eine Zahl umgewandelt wird, 0. Deshalb führt Ihr erstes Beispiel zu "a Bingo".

Sie müssen den strict-Parameter nicht verwenden, wenn Sie sich auf implizite Konvertierung verlassen oder wenn Ihre Datentypen gleich sind (z. B. bei der Suche nach einem String in einem Array von Strings). Andernfalls sollten Sie den strict-Parameter verwenden, genauso wie Sie === anstelle von == verwenden sollten, wenn Sie zwei Werte vergleichen, die vom gleichen Typ sein müssen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X