最好的方法来做一个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和工作