Comment feriez-vous cette déclaration de commutateur PHP?
Notez également que ce sont des versions beaucoup plus petites, le 1 que je dois créer aura beaucoup plus de valeur ajoutée.
Version 1:
switch ($p) {
case 'home':
case '':
$current_home = 'current';
break;
case 'users.online':
case 'users.location':
case 'users.featured':
case 'users.new':
case 'users.browse':
case 'users.search':
case 'users.staff':
$current_users = 'current';
break;
case 'forum':
$current_forum = 'current';
break;
}
Version 2:
switch ($p) {
case 'home':
$current_home = 'current';
break;
case 'users.online' || 'users.location' || 'users.featured' || 'users.browse' || 'users.search' || 'users.staff':
$current_users = 'current';
break;
case 'forum':
$current_forum = 'current';
break;
}
UPDATE - Résultats des tests
J'ai effectué des tests de vitesse sur 10 000 itérations,
Time1: 0.0199389457703 // instructions If
Time2: 0.0389049446106 // instructions switch
Time3: 0.106977939606 // Tableaux
Pour toute situation où vous avez une chaîne inconnue et que vous devez déterminer laquelle des chaînes autres auxquelles elle correspond, la seule solution qui ne soit pas ralentie à mesure que vous ajoutez d'autres éléments consiste à utiliser un tableau. , mais ont toutes les chaînes possibles comme clés. Ainsi, votre commutateur peut être remplacé par ce qui suit:
// used for $current_home = 'current';
$group1 = array(
'home' => True,
);
// used for $current_users = 'current';
$group2 = array(
'users.online' => True,
'users.location' => True,
'users.featured' => True,
'users.new' => True,
'users.browse' => True,
'users.search' => True,
'users.staff' => True,
);
// used for $current_forum = 'current';
$group3 = array(
'forum' => True,
);
if(isset($group1[$p]))
$current_home = 'current';
else if(isset($group2[$p]))
$current_users = 'current';
else if(isset($group3[$p]))
$current_forum = 'current';
else
user_error("\$p is invalid", E_USER_ERROR);
Cela n'a pas l'air aussi propre qu'une switch()
, mais c'est la seule solution fast qui n'inclut pas l'écriture d'une petite bibliothèque de fonctions et de classes pour la garder ordonnée. Il est toujours très facile d’ajouter des éléments aux tableaux.
case 'users.online' || 'users.location' || ...
est exactement le même que:
case True:
et que case
sera choisi pour toute valeur de $p
, à moins que $p
ne soit la chaîne vide.
||
N'a aucune signification particulière dans une instruction case
, vous ne comparez pas $p
à chacune de ces chaînes, vous vérifiez simplement si ce n'est pas False
.
Placez ces nombreuses valeurs dans un tableau et interrogez-le, car le casse semble masquer la sémantique sous-jacente de ce que vous essayez d'obtenir lorsqu'une variable chaîne est utilisée comme condition, ce qui rend plus difficile la lecture et la compréhension, par exemple :
$current_home = null;
$current_users = null;
$current_forum = null;
$lotsOfStrings = array('users.online', 'users.location', 'users.featured', 'users.new');
if(empty($p)) {
$current_home = 'current';
}
if(in_array($p,$lotsOfStrings)) {
$current_users = 'current';
}
if(0 === strcmp('forum',$p)) {
$current_forum = 'current';
}
Si quelqu'un d'autre devait maintenir votre code, il ferait certainement une double-prise sur la version 2 - c'est extrêmement non standard.
Je resterais avec la version 1. Je suis de l’école de bien que les déclarations de cas sans bloc de déclaration devrait avoir un commentaire explicite // fall through
à côté d’eux pour indiquer qu’il est effectivement votre intention de passer à travers, éliminant ainsi toute ambiguïté de si vous alliez gérer les cas différemment et oublié ou quelque chose.
Par souci d’exhaustivité, je ferai remarquer que la logique brisée de la "Version 2" peut être remplacée par une instruction switch qui fonctionne et également utiliser des tableaux à la fois pour la vitesse et la clarté, comme suit:
// utilisé pour $ current_home = 'current'; $ home_group = array ( 'home' => True, ); // utilisé pour $ current_users = 'current'; $ user_group = array ( 'users.online' => True, 'users.location' => True, 'users.featured' => True, 'users.new' => True, 'users.browse' => True, 'users.search' => True, 'users.staff' => True, ) ; // utilisé pour $ current_forum = 'current'; $ forum_group = array ( 'forum' => True, ); switch (true ) { case isset ($ home_group [$ p]): $ current_home = 'current'; Pause; case isset ($ user_group [$ p]): $ current_users = 'current'; Pause; case isset ($ forum_group [$ p]): $ current_forum = 'current'; Pause; défaut: erreur_utilisateur ("\ $ p n'est pas valide", E_USER_ERROR); }
La version 1 est certainement plus facile pour les yeux, plus claire quant à vos intentions, et plus facile à ajouter aux conditions de cas.
Je n'ai jamais essayé la deuxième version. Dans de nombreuses langues, cela ne serait même pas compilé car chaque étiquette de cas doit être évaluée à une expression constante.
Quelques autres idées non encore mentionnées:
switch(true){
case in_array($p, array('home', '')):
$current_home = 'current'; break;
case preg_match('/^users\.(online|location|featured|new|browse|search|staff)$/', $p):
$current_users = 'current'; break;
case 'forum' == $p:
$current_forum = 'current'; break;
}
Quelqu'un se plaindra probablement de problèmes de lisibilité avec # 2, mais je n'aurais aucun problème à hériter d'un tel code.
Aucune version 2 ne fonctionne réellement, mais si vous voulez ce type d’approche, vous pouvez procéder comme suit (probablement pas le plus rapide, mais sans doute plus intuitif):
switch (true) {
case ($var === 'something' || $var === 'something else'):
// do some stuff
break;
}
Je préfère définitivement la version 1. La version 2 peut nécessiter moins de lignes de code, mais il sera extrêmement difficile à lire une fois que vous aurez beaucoup de valeurs, comme vous le prédisez.
(Honnêtement, je ne savais même pas que la version 2 était légale jusqu'à présent. Je ne l'avais jamais vue ainsi.)
En combinaison avec variables variables, vous aurez plus de flexibilité:
<?php
$p = 'home'; //For testing
$p = ( strpos($p, 'users') !== false? 'users': $p);
switch ($p) {
default:
$varContainer = 'current_' . $p; //Stores the variable [$current_"xyORz"] into $varContainer
${$varContainer} = 'current'; //Sets the VALUE of [$current_"xyORz"] to 'current'
break;
}
//For testing
echo $current_home;
?>
Pour en savoir plus, consultez variables variables et les exemples que j'ai soumis au manuel php:
Exemple 1: http://www.php.net/manual/fr/language.variables.variable.php#105293
Exemple 2: http://www.php.net/manual/fr/language.variables.variable.php#105282
PS: Cet exemple de code est SMALL AND SIMPLE, exactement comme je l’aime. C'est testé et fonctionne aussi
Je pense que la version 1 est la voie à suivre. C'est beaucoup plus facile à lire et à comprendre.
peut être
switch ($variable) {
case 0:
exit;
break;
case (1 || 3 || 4 || 5 || 6):
die(var_dump('expression'));
default:
die(var_dump('default'));
# code...
break;
}
if( in_array( $test, $array1 ) )
{
// do this
}
else if( stristr( $test, 'commonpart' ) )
{
// do this
}
else
{
switch( $test )
{
case 1:
// do this
break;
case 2:
// do this
break;
default:
// do this
break;
}
}
De nos jours tu peux faire ...
switch ([$group1, $group2]){
case ["users", "location"]:
case ["users", "online"]:
Ju_le_do_the_thing();
break;
case ["forum", $group2]:
Foo_the_bar();
break;
}