Stacking Multiple Ternary Operators in PHP

后端 未结 8 2164
忘了有多久
忘了有多久 2020-11-22 03:49

This is what I wrote :

 $Myprovince = (
($province == 6) ? \"city-1\" :
($province == 7) ? \"city-2\" :
($province == 8) ? \"city-3\" :
($province == 30) ? \         


        
相关标签:
8条回答
  • 2020-11-22 04:07

    Others have already suggested the right way of doing it but if you really want to use ternary operator you need to use parenthesis as:

    $province = 7;
     $Myprovince = (
     ($province == 6) ? "city-1" :
      (($province == 7) ? "city-2" :
       (($province == 8) ? "city-3" :
        (($province == 30) ? "city-4" : "out of borders")))
     );
    

    Updated Link

    0 讨论(0)
  • 2020-11-22 04:10

    Don't abuse the ternary operator for that sort of thing. It makes debugging near impossible to follow. Why not do something like

    switch($province) {
        case 6: $Myprovince = "city-1"; break;
        case 7: ...
    }
    

    or simply some chained if/then/else

    if ($province == 6) {
         $Myprovince = "city-1";
    } elseif ($province = ...) {
       ...
    }
    
    0 讨论(0)
  • 2020-11-22 04:10

    I understand this is a question about PHP, but since this is just an educational exercise anyways I thought you might be interested in learning that Ruby and Javascript actually behave the way you expect.

    Ruby:

    ree-1.8.7-2012.02 :009 > def foo x
    ree-1.8.7-2012.02 :010?>   x == 1 ? "city 1" : x == 2 ? "city 2" : "out of borders"
    ree-1.8.7-2012.02 :011?>   end
     => nil
    ree-1.8.7-2012.02 :012 > foo 1
     => "city 1"
    ree-1.8.7-2012.02 :013 > foo 2
     => "city 2"
    ree-1.8.7-2012.02 :014 > foo 3
     => "out of borders"
    

    Javascript:

    > function f(x) { return x == 1 ? "city 1" : x == 2 ? "city 2" : "out of borders"; }
    undefined
    > f(1)
    "city 1"
    > f(2)
    "city 2"
    > f(3)
    "out of borders"
    
    0 讨论(0)
  • 2020-11-22 04:16

    The ternary operator is evaluated from left to right. So if you don't group the expressions properly, you will get an unexpected result.

    PHP's advice is [docs]:

    It is recommended that you avoid "stacking" ternary expressions. PHP's behaviour when using more than one ternary operator within a single statement is non-obvious.

    Your code actually is evaluated as:

    (
        (
            (
                $province == 6 ? "city-1" : $province == 7
            ) ? "city-2" : 
            $province == 8
        ) ? "city-3" : $province == 30
    ) ? "city-4" : "out of borders";
    

    where it should be

    $province == 6 ? "city-1" : (
        $province == 7 ? "city-2" : (
            $province == 8 ? "city-3" : (
               $province == 30 ? "city-4" : "out of borders"
            )
        )
    );
    

    This code might look fine but someone will read it and they will need more time than they should to understand what this code is doing.


    You would be better off with something like this:

    $map = array( 6 = >'city-1', 
                  7 => 'city-2', 
                  8 => 'city-3', 
                 30 => 'city-4');
    
    $Myprovince = "out of borders";
    
    if(array_key_exists($province, $map)) {
        $Myprovince = $map[$province];
    }
    

    Or as @Jonah mentioned in his comment:

    $Myprovince = isset($map[$province]) ? $map[$province] : 'out of borders';
    
    0 讨论(0)
  • 2020-11-22 04:16

    Some people have suggested using a switch statement or an if/else statement. But I would use an array instead, to make it easier to maintain and easier to read:

    $provinces = array (
        6 => 'city-1',
        7 => 'city-2',
        8 => 'city-3',
        30 => 'city-4'
    );
    
    // then you can call:
    
    $Myprovince = isset($provinces[$province]) ? $provinces[$province] : 'out of borders';
    

    Why?

    The code will probably eventually be easier to manage. Maybe you'll want to add those province-to-city mappings from database one day.. etc.. That will be hard to maintain with a bunch of switch/case statements.

    0 讨论(0)
  • 2020-11-22 04:16

    Use switch instead. Ternary operators really shouldn't be used for more than single conditions, as they quickly become very difficult to understand.

    switch ($province) {
        case 6:
            $Myprovince = 'city-1';
            break;
        case 7:
            $Myprovince = 'city-2';
            break;
        case 8:
            $Myprovince = 'city-3';
            break;
        case 30:
            $Myprovince = 'city-4';
            break;
        default:
            $Myprovince = 'out of borders';
    }
    
    0 讨论(0)
提交回复
热议问题