PHP:切换具有多种条件,更好更优雅的方式


PHP: switch with multiple conditions, a better more elegant way?

这是我当前的代码,如果给定的字符串以特定字母开头我触发了一个函数...简单。。。

      switch ($string[0]) {
        case 'a':
            //do   X
            break;
        case 'b':
             //do   Y
            break;
        case 'c':
            //do   Z
            break;
        case 'd':
            //do   X
            break;
//
// etc etc with all alphabet
//
        default:
            //do some
            break;
    }

但我想触发一个函数 X,如果同时满足 a、b 和 c,如果另一组字母符合条件,则触发函数 Y......

我想知道是否有一种更优雅的方法可以做到这一点,而不是 26 个字母的开关。

我想我需要使用preg_match,但不确定如何...

我会提出两个建议:

  1. switch 语法允许您通过失败(省略一个案例和下一个案例之间的break)对多个案例执行相同的代码。

    switch ($string[0]) {
        case 'a':
        case 'b':
        case 'c':
            handle_A_B_C();
            break;
        case 'd':
        case 'e':
            handle_D_E();
            break;
        // ...etc.
    }
    
  2. 我喜欢使用 in_array() 以优雅、可读的方式进行多重相等比较。

    if (in_array($string[0], ['a', 'b', 'c'])) {
        handle_A_B_C();
    } elseif (in_array($string[0], ['d', 'e'])) {
        handle_D_E();
    }
    // ... etc.
    

如下@devon所述,您可以用range('a', 'c')代替['a', 'b', 'c']以提高可读性。如果您的案例在两个或三个以上的字母上触发,并且字母总是连续的,那将是一个很好的接触。

您可以堆叠案例,但是,您还需要小心使用中断。 中断意味着它不会检查任何其他案例。 如果 'c' 可以同时执行 x() 和 y(),你会想要这样的东西:

switch ($string[0]) {
    case 'a':
    case 'b':
    case 'c':
        x();
    case 'c':
    case 'd':
        y();
}

除了其他答案之外,还可以通过定义地图/图例数组并循环使用它来使用它。

/*
Define legends function as a key,  letters array as value
*/
$legend=array (
    'process_abc'=>array('a','b','c'),
    'process_gpo'=>array('g','p','o')
);
/*
    loop through the legend and check if it exists within the array
*/
foreach ($legend as $function=>$letters){
     if (in_array($string[0],$letters)){
        call_user_func($function);
        break;
     }
}

function process_abc(){
    echo "ABC was called";  
}
function process_gpo(){
    echo "GPO was called";  
}

您也可以像这样使用开关:

$char = 'z';
switch (true) {
    case strpos('abcdef', $char) !== -1:
        echo 'Do A';
    break;
    case strpos('ghijkl', $char) !== -1:
        echo 'Do B';
    break;
    case strpos('mnopqr', $char) !== -1:
        echo 'Do C';
    break;
    case strpos('stuvw', $char) !== -1:
        echo 'Do D';
    break;
    case strpos('xyz', $char) !== -1:
        echo 'Do E';
    break;
}

或者对case进行分组:

switch ($char) {
    case 'a':
    case 'b':
    case 'c':
        echo 'Do A';
    break;
    case 'd':
    case 'e':
    // ...
        echo 'Do B';
    break;
    // ...
}

或者这个:

$actions = [
    'abcde':  function () { return 'Do A'; },
    'fghij':  function () { return 'Do B'; },
    'klmno':  function () { return 'Do C'; },
    'pqrst':  function () { return 'Do D'; },
    'uvwxyz': function () { return 'Do E'; },
];
$char = 'n';
foreach ($actions as $haystack => $callback) {
    if (strpos($haystack, $char) !== -1) {
        echo $callback();
    }
}