最好的方法是在每个案例中使用多个值的PHP交换机?

时间:2022-09-25 15:30:23

How would you do this PHP switch statement?

如何做这个PHP切换语句?

Also note that these are much smaller versions, the 1 I need to create will have a lot more values added to it.

还要注意,这些是更小的版本,我需要创建的1将有更多的值添加到其中。

Version 1:

版本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:

版本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 - Test Results

更新——测试结果

I ran some speed test on 10,000 iterations,

我在10,000次迭代中运行了一些速度测试,

Time1: 0.0199389457703 // If statements
Time2: 0.0389049446106 //switch statements
Time3: 0.106977939606 // Arrays

时间1:0.0199389457703 / If语句时间2:0.0389049446106 //切换语句时间3:0.106977939606 //数组

12 个解决方案

#1


48  

For any situation where you have an unknown string and you need to figure out which of a bunch of other strings it matches up to, the only solution which doesn't get slower as you add more items is to use an array, but have all the possible strings as keys. So your switch can be replaced with the following:

对于任何情况,你有一个字符串,你需要找出哪些未知的一堆其他字符串匹配,唯一的解决办法也不会慢您添加更多的项目是使用一个数组,但所有可能的字符串作为键。因此,您的开关可以替换为以下内容:

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

This doesn't look as clean as a switch(), but it is the only fast solution which doesn't include writing a small library of functions and classes to keep it tidy. It is still very easy to add items to the arrays.

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

#2


24  

Version 2 does not work!!

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

is exactly the same as:

和:

case True:

and that case will be chosen for any value of $p, unless $p is the empty string.

这种情况下,任何$p的值都会被选择,除非$p是空字符串。

|| Does not have any special meaning inside a case statement, you are not comparing $p to each of those strings, you are just checking to see if it's not False.

||在case语句中没有任何特殊意义,你不是在比较$p与每一个字符串,你只是检查它是否为假。

#3


8  

Put those many values into an array and query the array, as the switch-case seems to hide the underlying semantics of what you're trying to achieve when a string variable is used as the condition, making it harder to read and understand, e.g.:

将这些值放入数组并查询数组,因为当字符串变量作为条件使用时,switch case似乎隐藏了要实现的目标的底层语义,这使得读取和理解变得更加困难,例如:

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

#4


4  

If anyone else was ever to maintain your code, they would almost certainly do a double take on version 2 -- that's extremely non-standard.

如果有其他人维护您的代码,他们几乎肯定会对版本2进行双重检查——这是非常不标准的。

I would stick with version 1. I'm of the school of though that case statements without a statement block of their own should have an explicit // fall through comment next to them to indicate it is indeed your intent to fall through, thereby removing any ambiguity of whether you were going to handle the cases differently and forgot or something.

我会坚持使用版本1。我尽管学院的情况下自己的语句没有语句块应该显式/旁边/秋天通过注释来表示这的确是你的意图落空,从而消除任何模棱两可的你要去处理不同的情况下,是否忘记了什么的。

#5


4  

For the sake of completeness, I'll point out that the broken "Version 2" logic can be replaced with a switch statement that works, and also make use of arrays for both speed and clarity, like so:

为了完整性起见,我将指出,坏掉的“Version 2”逻辑可以替换为一个可以工作的switch语句,并且为了速度和清晰度也可以使用数组,如下所示:

// used for $current_home = 'current';
$home_group = array(
    'home'  => True,
);

// used for $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,
);

// used for $current_forum = 'current';
$forum_group = array(
    'forum'     => True,
);

switch (true) {
    case isset($home_group[$p]):
        $current_home = 'current';
        break;
    case isset($user_group[$p]):
        $current_users = 'current';
        break;
    case isset($forum_group[$p]):
        $current_forum = 'current';
        break;
    default:
        user_error("\$p is invalid", E_USER_ERROR);
}    

#6


3  

Version 1 is certainly easier on the eyes, clearer as to your intentions, and easier to add case-conditions to.

版本1当然更容易理解,更清楚您的意图,更容易添加case-conditions。

I've never tried the second version. In many languages, this wouldn't even compile because each case labels has to evaluate to a constant-expression.

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

#7


2  

Some other ideas not mentioned yet:

还有一些没有提到的观点:

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

Someone will probably complain about readability issues with #2, but I would have no problem inheriting code like that.

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

#8


1  

I definitely prefer Version 1. Version 2 may require less lines of code, but it will be extremely hard to read once you have a lot of values in there like you're predicting.

我当然更喜欢第一版。版本2可能需要更少的代码行,但是一旦您有了大量的值,就像您预测的那样,它将非常难读。

(Honestly, I didn't even know Version 2 was legal until now. I've never seen it done that way before.)

(老实说,直到现在我才知道版本2是合法的。我以前从未见过这样做。

#9


1  

No version 2 doesn't actually work but if you want this kind of approach you can do the following (probably not the speediest, but arguably more intuitive):

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

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

切换(true) {case ($var = 'something' || $var === 'something else'): //做一些事情break;}

#10


0  

I think version 1 is the way to go. It is a lot easier to read and understand.

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

#11


0  

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

#12


0  

Switch in combination with variable variables will give you more flexibility:

结合变量切换会给你更大的灵活性:

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

To learn more, checkout variable variables and the examples I submitted to php manual:
Example 1: http://www.php.net/manual/en/language.variables.variable.php#105293
Example 2: http://www.php.net/manual/en/language.variables.variable.php#105282

要了解更多信息,请查看变量和我提交给php手册的示例:示例1:http://www.php.net/manual/en/language.variables.variables.php #105293示例2:http://www.php.net/manual/en/language.variable.php #105282

PS: This example code is SMALL AND SIMPLE, just the way I like it. It's tested and works too

PS:这个示例代码非常简单,就是我喜欢的方式。它也经过测试和工作。

#1


48  

For any situation where you have an unknown string and you need to figure out which of a bunch of other strings it matches up to, the only solution which doesn't get slower as you add more items is to use an array, but have all the possible strings as keys. So your switch can be replaced with the following:

对于任何情况,你有一个字符串,你需要找出哪些未知的一堆其他字符串匹配,唯一的解决办法也不会慢您添加更多的项目是使用一个数组,但所有可能的字符串作为键。因此,您的开关可以替换为以下内容:

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

This doesn't look as clean as a switch(), but it is the only fast solution which doesn't include writing a small library of functions and classes to keep it tidy. It is still very easy to add items to the arrays.

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

#2


24  

Version 2 does not work!!

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

is exactly the same as:

和:

case True:

and that case will be chosen for any value of $p, unless $p is the empty string.

这种情况下,任何$p的值都会被选择,除非$p是空字符串。

|| Does not have any special meaning inside a case statement, you are not comparing $p to each of those strings, you are just checking to see if it's not False.

||在case语句中没有任何特殊意义,你不是在比较$p与每一个字符串,你只是检查它是否为假。

#3


8  

Put those many values into an array and query the array, as the switch-case seems to hide the underlying semantics of what you're trying to achieve when a string variable is used as the condition, making it harder to read and understand, e.g.:

将这些值放入数组并查询数组,因为当字符串变量作为条件使用时,switch case似乎隐藏了要实现的目标的底层语义,这使得读取和理解变得更加困难,例如:

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

#4


4  

If anyone else was ever to maintain your code, they would almost certainly do a double take on version 2 -- that's extremely non-standard.

如果有其他人维护您的代码,他们几乎肯定会对版本2进行双重检查——这是非常不标准的。

I would stick with version 1. I'm of the school of though that case statements without a statement block of their own should have an explicit // fall through comment next to them to indicate it is indeed your intent to fall through, thereby removing any ambiguity of whether you were going to handle the cases differently and forgot or something.

我会坚持使用版本1。我尽管学院的情况下自己的语句没有语句块应该显式/旁边/秋天通过注释来表示这的确是你的意图落空,从而消除任何模棱两可的你要去处理不同的情况下,是否忘记了什么的。

#5


4  

For the sake of completeness, I'll point out that the broken "Version 2" logic can be replaced with a switch statement that works, and also make use of arrays for both speed and clarity, like so:

为了完整性起见,我将指出,坏掉的“Version 2”逻辑可以替换为一个可以工作的switch语句,并且为了速度和清晰度也可以使用数组,如下所示:

// used for $current_home = 'current';
$home_group = array(
    'home'  => True,
);

// used for $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,
);

// used for $current_forum = 'current';
$forum_group = array(
    'forum'     => True,
);

switch (true) {
    case isset($home_group[$p]):
        $current_home = 'current';
        break;
    case isset($user_group[$p]):
        $current_users = 'current';
        break;
    case isset($forum_group[$p]):
        $current_forum = 'current';
        break;
    default:
        user_error("\$p is invalid", E_USER_ERROR);
}    

#6


3  

Version 1 is certainly easier on the eyes, clearer as to your intentions, and easier to add case-conditions to.

版本1当然更容易理解,更清楚您的意图,更容易添加case-conditions。

I've never tried the second version. In many languages, this wouldn't even compile because each case labels has to evaluate to a constant-expression.

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

#7


2  

Some other ideas not mentioned yet:

还有一些没有提到的观点:

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

Someone will probably complain about readability issues with #2, but I would have no problem inheriting code like that.

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

#8


1  

I definitely prefer Version 1. Version 2 may require less lines of code, but it will be extremely hard to read once you have a lot of values in there like you're predicting.

我当然更喜欢第一版。版本2可能需要更少的代码行,但是一旦您有了大量的值,就像您预测的那样,它将非常难读。

(Honestly, I didn't even know Version 2 was legal until now. I've never seen it done that way before.)

(老实说,直到现在我才知道版本2是合法的。我以前从未见过这样做。

#9


1  

No version 2 doesn't actually work but if you want this kind of approach you can do the following (probably not the speediest, but arguably more intuitive):

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

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

切换(true) {case ($var = 'something' || $var === 'something else'): //做一些事情break;}

#10


0  

I think version 1 is the way to go. It is a lot easier to read and understand.

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

#11


0  

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

#12


0  

Switch in combination with variable variables will give you more flexibility:

结合变量切换会给你更大的灵活性:

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

To learn more, checkout variable variables and the examples I submitted to php manual:
Example 1: http://www.php.net/manual/en/language.variables.variable.php#105293
Example 2: http://www.php.net/manual/en/language.variables.variable.php#105282

要了解更多信息,请查看变量和我提交给php手册的示例:示例1:http://www.php.net/manual/en/language.variables.variables.php #105293示例2:http://www.php.net/manual/en/language.variable.php #105282

PS: This example code is SMALL AND SIMPLE, just the way I like it. It's tested and works too

PS:这个示例代码非常简单,就是我喜欢的方式。它也经过测试和工作。