2010-08-19 12 views
57

Gibt es trotzdem so, dass der folgende Code immer noch einen Switch verwendet und b nicht a zurückgibt? Vielen Dank!make switch === Vergleich not == Vergleich In PHP

$var = 0; 
switch($var) { 
    case NULL : return 'a'; break; 
    default : return 'b'; break; 
} 

verwenden, wenn Aussagen, natürlich, können Sie es wie folgt tun würde:

$var = 0; 
if($var === NULL) return 'a'; 
else return 'b'; 

Aber für komplexere Beispiele, wird dies ausführlich.

Antwort

40

Sie können leider keine === Vergleich in einer switch-Anweisung, da nach den switch() documentation verwenden:

Beachten Sie, dass Schalter/Fall tut losen Vergleich.

Das bedeutet, dass Sie eine Problemumgehung finden müssen. Von the loose comparisons table, könnte man sich die Tatsache zunutze machen, dass NULL == "0" nach Art Casting falsch ist:

<?php 
$var = 0; 
switch((string)$var) 
{ 
    case "" : echo 'a'; break; // This tests for NULL or empty string 
    default : echo 'b'; break; // Everything else, including zero 
} 
// Output: 'b' 
?> 

Live Demo

+3

Was ist der Sinn von 'switch'? Durchfallen? – strager

+0

Nun, es gibt andere Umstände (nicht nur mit NULL), mit denen ich gerne arbeiten würde. –

+3

Das wird nicht funktionieren! Dies ist äquivalent zu 'if ($ var == is_null ($ var))', was niemals wahr sein wird (wenn '$ var'' NULL' ist, wird es 'NULL == true' sein). –

1

Wechslern Verwendung === Vergleich nicht == Vergleich In PHP

Leider switch verwendet losen Vergleich und soweit ich weiß gibt es keine Möglichkeit, das zu ändern.

1

Nein. Von der manual page:

Beachten Sie, dass Schalter/Gehäuse loose comparison.

Wenn Sie nur zwei Bedingungen haben, verwenden Sie ein if wie Ihr zweites Beispiel. Andernfalls prüfen NULL ersten und schalten Sie die anderen Möglichkeiten:

if (is_null($var)) 
{ 
    return 'a'; 
} 

switch ($var) 
{ 
    // ... 
} 
0

Das ist nicht möglich.

Sie können jedoch setzen die if Aussagen innen die switch:

switch($var) { 
    // Loose cases here 

    case 0: 
     if($var === NULL) { 
      return 'a'; 
     } 

     // Fall through 

    default: 
     return 'b'; 
} 

Oder einfach:

switch($var) { 
    // Loose cases here 

    default: 
     if($var === NULL) { 
      return 'a'; 
     } 

     return 'b'; 
} 
+7

An diesem Punkt, warum mit dem Schalter zu tun? Sie könnten sogar 'switch (true) {case $ var === null: ...} – ircmaxell

+0

@ ircmaxell, ich ging davon aus, dass das OP die Durchgriffslogik oder sonst einen Grund haben will, "Switch" zu verwenden, der über die strenge Überprüfung hinausgeht. – strager

54

Eine Möglichkeit, dies tun könnte, ist zu tun, was ich denke, der als ein Rückwärts-Schalter (es kann einen offiziellen Namen dafür geben). Die Idee ist, dass Sie setzen true oder false an der Spitze und dann Ihre Bedingungen in den case Aussagen.

switch(true) 
{ 
    case ($var === NULL): 
    return 'a'; 
    break; 
    case ($var === 0): 
    return 'b'; 
    break; 
    default: 
    return 'c'; 
} 
+14

Was ist der Sinn dieses Vs nur eines If/Elseif Blocks? –

+3

Es hat keinen Sinn, dies zu tun, und wenn Sie gegen andere Werte überprüfen möchten, wird die Syntax ziemlich peinlich. –

+25

Nichts wirklich anders als Codierungsstil, das Endergebnis wird das gleiche sein. Ich denke, Schalter sehen etwas aufgeräumter aus, wenn Sie viele Bedingungen haben. Ich würde lieber 10 Fälle betrachten, als wenn/elseif/elseif/elseif usw. –

0

Sie können auch auf die Art der Variablen wechseln:

switch (gettype($var)) { 
... 
} 
+0

Schlechte Idee - Von Die Dokumentation: 'Verwenden Sie nie gettype(), um nach einem bestimmten Typ zu suchen, da die zurückgegebene Zeichenfolge möglicherweise in einer zukünftigen Version geändert wird. Außerdem ist es auch langsam, da es einen String-Vergleich beinhaltet. Verwenden Sie stattdessen die is_ * -Funktionen. –

+0

Wenn gettype() ändert, würde die Funktion nutzlos und die Sprache weniger zuverlässig. Mit is_ * wird die Frage nach dem Schalter nicht beantwortet. Für den Rest stimme ich zu :) – greg

7

Nicht mit switch - es ist nur so genannte "lose" Vergleiche. Sie können es immer durch einen if/else if Block ersetzen, indem Sie === verwenden.

+0

beziehen Sie sich auf Ihre Erfahrung oder Dokumentation? Wenn das später, bitte posten Sie einen Link – TMS

+0

Bereits verlinkt :) –

+1

Sie * können * tatsächlich tun dies mit 'switch' (siehe meine Antwort), obwohl ich denke, dass' if-else' ist besser für diesen bestimmten Job. – DaveRandom

2

Vermutlich schalten Sie die Variable ein und erwarten ganze Zahlen. Warum prüfen Sie nicht vorher einfach den Integer-Status der Variablen mit is_int($val)?

1

benutze ich nur

$var === null and $var = -1; // since switch is not type-safe 
switch ($var) { 
    case 0: 
     # this tests for zero/empty string/false 
     break; 
    case -1: 
     # this tests for null 
     break; 
} 

ich denke, das sieht immer noch sehr gut lesbar, wenn der Kommentar mit Start // zurückgelassen wird (und die Ausgänge diejenigen mit # sind wahrscheinlich am besten gelöscht).

0

Einer der beste Weg ist, um NULL-Wert zu überprüfen, mit is_null

<?php 
echo getValue(); 
function getValue() 
{ 
    $var = 0; 
    switch(true) { 
     case is_null($var) : return 'a'; break; 
     default : return 'b'; break; 
    } 
} 
?> 
+0

Das beste ist jedoch '=== null', da es den überflüssigen Funktionsaufruf-Overhead vermeidet. – Antti29

2

ich das gleiche Problem in einem Schalter mit String mit Zahlen hatte („15.2“ ist gleich „15.20“ in einem Schalter für php)

ich das Problem des Hinzufügen eines Briefes vor dem Text gelöst

$var = '15.20'; 
switch ('#'.$var) { 
    case '#15.2' : 
     echo 'wrong'; 
    break; 
    case '#15.20' : 
     echo 'right'; 
    break; 
} 
0

zu vergleichen, aus dem Beispielcode Rechnet man, ich glaube, Sie haben eine Reihe von regelmäßigen cas es und ein Sonderfall (hier, null).

Die einfachste ich herausfinden kann, ist, diesen Fall vor dem Wechsel zu handhaben:

if ($value === null) { 
    return 'null'; 
} 

switch ($value) { 
    case 0: 
     return 'zero'; 
    case 1: 
     return 'one'; 
    case 2: 
     return 'two'; 
} 

Vielleicht auch hinzufügen, um einen Kommentar zu erinnern null unerwartet den 0 Fall passen würde (auch das Gegenteil, 0 würde ein null passen Fall).