最好的方法来做一个PHP开关每个案件多个值?

你将如何做这个PHP开关语句?

另外请注意,这些是更小的版本,我需要创build将有更多的值添加到它。

版本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; } 

版本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; } 

更新 – testing结果

我跑了一万次迭代的速度testing,

时间1:0.0199389457703 //如果语句
时间2:0.0389049446106 //开关语句
时间3:0.106977939606 //数组

对于任何情况下,你有一个未知的string,你需要找出一堆其他string中的哪一个匹配,唯一的解决scheme不会慢得多,因为你添加更多的项目是使用一个数组,但拥有所有可能的string作为键。 所以你的开关可以用下面的代替:

 // 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); 

这看起来不像switch()那样干净,但是它是唯一的快速解决scheme,它不包括编写一个小函数库和类库来保持整洁。 将项目添加到数组中仍然非常容易。

版本2不起作用!

 case 'users.online' || 'users.location' || ... 

与以下内容完全相同:

 case True: 

那么这个case将被select为$p任何值,除非$p是空string。

||case语句中没有任何特殊的含义,你没有比较$p到每个string,你只是检查是否不是False

把这些多个值放到一个数组中并查询数组,因为switch-case似乎隐藏了当stringvariables用作条件时要实现的基本语义,使得它更难以阅读和理解,例如:

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

如果其他人曾经维护过你的代码,那么他们几乎肯定会对版本2进行双重处理 – 这是非常不规范的。

我会坚持版本1.我是学校,虽然没有自己的声明块的情况下应该有一个明确的// fall through旁边的评论,以表明它确实是你的意图,从而消除任何你是否要处理不同的情况,忘记或什么的模棱两可。

版本1当然更容易,对你的意图更清楚,更容易增加案例条件。

我从来没有尝试过第二个版本。 在许多语言中,甚至不会编译,因为每个case标签都必须计算为一个常量expression式。

为了完整起见,我将指出,破坏的“版本2”逻辑可以用一个可以工作的switch语句replace,并且可以使用数组来提高速度和清晰度,如下所示:

 //用于$ current_home ='current';
 $ home_group = array(
     'home'=>确实,
 );

 //用于$ current_users ='current';
 $ user_group = array(
     'users.online'=>确实,
     'users.location'=>确实,
     'users.featured'=>确实,
     'users.new'=>确实,
     'users.browse'=>的确,
     'users.search'=>确实,
     'users.staff'=>的确,
 );

 //用于$ current_forum ='current';
 $ forum_group = array(
     'forum'=>确实,
 );

开关(true){
    情况isset($ home_group [$ p]):
         $ current_home ='current';
        打破;
     case isset($ user_group [$ p]):
         $ current_users ='current';
        打破;
    案件isset($ forum_group [$ p]):
         $ current_forum ='current';
        打破;
    默认:
         user_error(“\ $ p无效”,E_USER_ERROR);
 }    

我绝对更喜欢版本1.版本2可能需要更less的代码行,但是一旦你有很多值,就像你预测的一样,这将是非常难以阅读的。

(老实说,我甚至都不知道第二版是否合法,我以前从来没有见过这样做。)

没有版本2实际上不工作,但如果你想要这种方法,你可以做以下(可能不是最快的,但可以说更直观):

switch (true) {
case ($var === 'something' || $var === 'something else'):
// do some stuff
break;
}

尚未提到的其他一些想法:

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

有人可能会抱怨#2的可读性问题,但我没有问题inheritance这样的代码。

我认为版本1是要走的路。 阅读和理解起来要容易得多。

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

variablesvariables结合使用会给你更多的灵活性:

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

要了解更多,结帐variablesvariables和我提交给php手册的例子:
示例1 : http : //www.php.net/manual/en/language.variables.variable.php#105293
例2 : http : //www.php.net/manual/en/language.variables.variable.php#105282

PS:这个例子代码很简单 ,就像我喜欢的那样。 它的testing和工作