Y a-t-il un moyen de faire en sorte que le code suivant utilise toujours un commutateur et retourne b
not a
? Merci!
$var = 0;
switch($var) {
case NULL : return 'a'; break;
default : return 'b'; break;
}
En utilisant if, bien sûr, vous le feriez comme ceci:
$var = 0;
if($var === NULL) return 'a';
else return 'b';
Mais pour des exemples plus complexes, cela devient verbeux.
Désolé, vous ne pouvez pas utiliser une comparaison ===
dans une instruction switch car, selon la documentation switch () :
Notez que switch/case fait perdre la comparaison.
Cela signifie que vous devrez trouver une solution de contournement. À partir de le tableau de comparaison lâche , vous pouvez utiliser le fait que NULL == "0"
est faux en spécifiant le type:
<?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'
?>
Pas avec switch
- cela ne fait que des comparaisons "lâches". Vous pouvez toujours le remplacer par un bloc if/else if
, en utilisant ===
.
Vraisemblablement, vous activez la variable et attendez des entiers. Pourquoi ne pas simplement vérifier le statut entier de la variable au préalable en utilisant is_int($val)
?
J'ai eu le même problème dans un commutateur avec une chaîne contenant des nombres ("15.2" est égal à "15.20" dans un commutateur pour php)
J'ai résolu le problème en ajoutant une lettre avant le texte à comparer
$var = '15.20';
switch ('#'.$var) {
case '#15.2' :
echo 'wrong';
break;
case '#15.20' :
echo 'right';
break;
}
make switch utilise === comparaison pas == comparaison en PHP
Malheureusement, switch
utilise une comparaison approximative et, autant que je sache, il n’ya aucun moyen de changer cela.
Nan. De la page de manuel :
Notez que switch/case fait perdre la comparaison .
Si vous n'avez que deux conditions, utilisez une if
comme votre deuxième exemple. Sinon, vérifiez d'abord NULL
et activez les autres possibilités:
if (is_null($var))
{
return 'a';
}
switch ($var)
{
// ...
}
L'instruction switch en php ne fait que des comparaisons lâches (==) voir http://www.php.net/manual/en/control-structures.switch.php
Utilisez if/elseif/else si vous avez besoin de comparaisons strictes.
Voici votre code d'origine dans une instruction switch "stricte":
switch(true) {
case $var === null:
return 'a';
default:
return 'b';
}
Cela peut également gérer des instructions de commutateur plus complexes comme ceci:
switch(true) {
case $var === null:
return 'a';
break;
case $var === 4:
case $var === 'foobar':
return 'b';
default:
return 'c';
break;
}
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 toujours très lisible si le commentaire commençant par //
est laissé (et ceux qui commencent par #
sont probablement mieux supprimés).
Ce n'est pas possible.
Vous pouvez cependant mettre les instructions if
inside 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';
}
L’un des meilleurs moyens 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;
}
}
?>
Vous pouvez également activer le type de la variable:
switch (gettype($var)) {
...
}
Si vous voulez tester à la fois valeur _ et type de votre variable, créez un nouveau variable de chaîne contenant les deux informations et comparez-le avec vos différents scénarios (par concaténation). ) cela devrait fonctionner pour votre cas si vous implémentez tous les types possibles (selon gettype () documentation ), exemple:
<?php
$var= 9999;
$valueAndTypeOfVar = (string)$var.' '.gettype($var);
switch($valueAndTypeOfVar) {
case "$var boolean" : echo 'a'; break;
case "$var integer" : echo 'b'; break;
case "$var double" : echo 'c'; break;
case "$var string" : echo 'd'; break;
case "$var array" : echo 'e'; break;
case "$var object" : echo 'f'; break;
case "$var resource" : echo 'g'; break;
case "$var NULL" : echo 'h'; break;
case "$var unknown type" : echo 'i'; break;
default: echo 'j'; break;
}
// Outputs: 'b'
?>
Créez une classe semblable à une assertion et mettez-y toute la logique que vous voulez; tant que les méthodes "true" renvoient $this
(et rien d'autre pour éviter les faux positifs).
class Haystack
{
public $value;
public function __construct($value)
{
$this->value = $value;
}
public function isExactly($n)
{
if ($n === $this->value)
return $this;
}
}
$var = new Haystack(null);
switch ($var) {
case $var->isExactly(''):
echo "the value is an empty string";
break;
case $var->isExactly(null):
echo "the value is null";
break;
}
Ou vous pouvez placer votre commutateur dans la classe actuelle:
class Checker
{
public $value;
public function __construct($value)
{
$this->value = $value;
}
public function isExactly($n)
{
if ($n === $this->value)
return $this;
}
public function contains($n)
{
if (strpos($this->value, $n) !== false)
return $this;
}
public static function check($str)
{
$var = new self($str);
switch ($var) {
case $var->isExactly(''):
return "'$str' is an empty string";
case $var->isExactly(null):
return "the value is null";
case $var->contains('hello'):
return "'$str' contains hello";
default:
return "'$str' did not meet any of your requirements.";
}
}
}
var_dump(Checker::check('hello world')); # string(28) "'hello world' contains hello"
Bien sûr, vous voudrez peut-être réévaluer ce que vous voulez faire avec ce que vous vérifiez et utiliser à la place une vraie bibliothèque de validation.
Extrapolant à partir de votre exemple de code, je suppose que vous avez un tas de cas réguliers et un cas spécial (ici, null
).
Le plus simple que je puisse comprendre est de traiter ce cas avant le changement:
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 pour rappeler que null
correspondrait de manière inattendue au cas 0
(le contraire, 0
correspondrait à un cas null
).