En PHP, le contrôle switch gère mal l’entier 0 et les chaînes de caractères
J’ai rencontré au détour d’un code PHP un drôle de comportement de la structure de contrôle switch.
switch considère que toute chaîne de caractères équivaut à l’entier 0 si jamais ce cas est rencontré en premier.
switch considère que toute chaîne de caractères équivaut à l’entier 0 si jamais ce cas est rencontré en premier.
Tout le monde connaît la structure suivante :
Exemple :
<?php
...
switch($variable) {
case 'valeur1':
// Business 1
break;
case 'valeur2':
// Business 2
break;
default:
// Business par défaut
}
Evidemment on peut remplacer les chaînes valeur1 et valeur2 par des constantes : CAS1 et CAS2.Exemple :
<?php
...
define('CAS1', 'valeur1');
define('CAS2', 'valeur2');
switch($variable) {
case CAS1:
// Business 1
break;
case CAS2:
// Business 2
break;
default:
// Business par défaut
}
Jusque-là vous me suivez. Mais là où la plupart d’entre vous ne me suivront plus, c’est lorsqu’une telle constante utilisée derrière un case représente la valeur entière 0 alors que la variable de contrôle $variable est une chaîne de caractères, c’est le case 0 qui l’emporte s’il est rencontré en premier, comme dans le cas suivant :
<?php
define('CAS1', 0);
define('CAS2', 'foobar');
// index.php?parametre=foobar
$variable = $_GET['parametre'];
switch($variable) {
case CAS1:
// Je l'emporte toujours
break;
case CAS2:
// Business 2
break;
default:
// Business par défaut
}
Mais pas dans le cas ci-dessous, car il n’est pas rencontré en premier :
<?php
define('CAS1', 0);
define('CAS2', 'foobar');
// index.php?parametre=foobar
$variable = $_GET['parametre'];
switch($variable) {
case CAS2:
// Je l'emporte
break;
case CAS1:
// Je ne l'emporte pas car je suis placé après un "better match".
break;
default:
// Business par défaut
}
Incroyable ! C’est comme si la construction switch nous disait que quelle que soit la valeur de la variable $variable, elle est équivalente à l’entier 0 ! Drôle de cast dégradé… Alors prenez garde à ce cas plus que douteux !