2010-08-19 6 views
57

Y at-il moyen de faire en sorte que le code suivant utilise encore un commutateur et renvoie b pas a? Merci!make switch utiliser === comparaison non == comparaison En PHP

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

Utiliser si les déclarations, bien sûr, vous devriez le faire comme ceci:

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

Mais pour des exemples plus complexes, cela devient bavard.

Répondre

40

Désolé, vous ne pouvez pas utiliser une comparaison === dans une instruction switch, puisque selon le switch() documentation:

Notez que commutateur/cas ne lâche comparaison.

Cela signifie que vous devrez trouver une solution de contournement. De the loose comparisons table, vous pouvez faire usage du fait que NULL == "0" est faux par type coulée:

<?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

Alors, quel est le point de 'switch'? Tomber dans? – strager

+0

Eh bien, il y a d'autres circonstances (pas seulement avec les valeurs NULL) avec lesquelles j'aimerais que cela fonctionne. –

+3

Cela ne fonctionnera pas! Ceci est équivalent à 'if ($ var == is_null ($ var))' qui ne sera jamais vrai (si '$ var' est' NULL', ce sera 'NULL == true'). –

1

make switch, utilisez === == comparaison ne comparaison PHP

Malheureusement switch utilise la comparaison lâche et autant que je sache, il n'y a aucun moyen de changer cela.

1

Non. À partir du manual page:

Notez que le commutateur/boîtier fait loose comparison.

Si vous n'avez que deux conditions, utilisez un if comme votre deuxième exemple. Sinon, vérifiez d'abord NULL et allumer les autres possibilités:

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

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

Ce n'est pas possible.

Vous pouvez toutefois mettre les if déclarations à l'intérieur le switch:

switch($var) { 
    // Loose cases here 

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

     // Fall through 

    default: 
     return 'b'; 
} 

Ou simplement:

switch($var) { 
    // Loose cases here 

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

     return 'b'; 
} 
+7

À ce stade, pourquoi s'embêter avec le commutateur? Vous pouvez même faire 'switch (true) {case $ var === null: ...} – ircmaxell

+0

@ ircmaxell, j'ai supposé que l'OP voulait une logique de "fall-through" ou sinon une raison d'utiliser 'switch' au-delà de la vérification stricte à certains moments – strager

54

Une façon vous pouvez faire est de faire ce que je pense que un commutateur en arrière (il peut y avoir un nom plus officiel pour cela). L'idée est que vous mettez true ou false en haut, puis vos conditions dans les instructions case.

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

quel est le but de ceci par rapport à un bloc if/elseif? –

+3

Il n'y a aucun intérêt à le faire, et si vous voulez vérifier par rapport à d'autres valeurs, la syntaxe deviendra plutôt embarrassante. –

+25

Rien d'autre que le style de codage, le résultat final sera le même. Je pense que les commutateurs semblent un peu plus ordonnés si vous avez un grand nombre de conditions. Je préfère regarder 10 cas que si/elseif/elseif/elseif etc. –

0

Vous pouvez également changer le type de la variable:

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

Mauvaise idée - De les docs: 'N'utilisez jamais gettype() pour tester un certain type, car la chaîne retournée pourrait être sujette à changement dans une future version. En outre, il est lent aussi, car il implique une comparaison de chaînes. Au lieu de cela, utilisez les fonctions is_ *. –

+0

Si gettype() change, cela rendrait la fonction inutile et le langage moins fiable. L'utilisation de is_ * ne répond pas à la question sur le commutateur. Pour le reste, je suis d'accord :) – greg

7

Pas avec switch - il ne fait que ce qu'on appelle des comparaisons "lâches". Vous pouvez toujours le remplacer par un bloc if/else if, en utilisant ===.

+0

parlez-vous de votre expérience ou de votre documentation? Si le plus tard, s'il vous plaît poster un lien – TMS

+0

Déjà lié :) –

+1

Vous réellement * peut * le faire avec 'switch' (voir ma réponse) même si je pense que« if-else »est mieux pour ce travail particulier. – DaveRandom

2

On suppose que vous allumez la variable et attendez des entiers. Pourquoi ne pas simplement vérifier l'état entier de la variable au préalable en utilisant is_int($val)?

1

je viens d'utiliser

$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; 
} 

Je pense que cela semble encore très lisible si le commentaire commence avec // est laissé derrière (et ceux commençant par # sont probablement mieux supprimés).

0

L'un des meilleur moyen est de vérifier la valeur NULL en utilisant is_null

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

Le meilleur, cependant, est '=== null' car il évite le surdébit inutile de l'appel de fonction. – Antti29

2

J'ai eu le même problème dans un commutateur avec un nombre contenant de chaîne (« 15,2 » est égal à « 15.20 » dans un commutateur pour php)

Je résolu le problème en ajoutant une lettre avant que le texte de comparer

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

en extrapolant à partir de votre code d'exemple, je suppose que vous avez un tas de PSC régulier es et un cas particulier (ici, null).

Le je peux plus simple de savoir est de traiter ce cas avant l'interrupteur:

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

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

Peut-être aussi ajouter un commentaire à retenir null sélectionnne inopinément le 0 cas (également au contraire, 0 correspondrait un null Cas).