在 PHP 中堆叠多个三元运算符

问题描述 投票:0回答:9

这是我写的:

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

但是对于每个字段,我都得到了值

city-4
。 我想使用三元运算符而不是
switch/if
,因为我想尝试一下,看看它是如何完成的。

这段代码有什么问题?

php operators ternary-operator
9个回答
113
投票

其他人已经建议了正确的方法,但如果您确实想使用三元运算符,则需要使用括号:

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

已更新链接


39
投票

三元运算符是从左到右计算的。因此,如果您没有正确对表达式进行分组,您将得到意想不到的结果。

PHP 的建议是 [文档]:

建议您避免“堆叠”三元表达式。当在单个语句中使用多个三元运算符时,PHP 的行为并不明显。

您的代码实际上被评估为:

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

它应该在哪里

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

这段代码可能看起来不错,但有人会阅读它,并且他们需要更多的时间来理解这段代码的作用。


这样的事情你会更好:

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

或者正如@Jonah在他的评论中提到的:

$Myprovince = isset($map[$province]) ? $map[$province] : 'out of borders';

19
投票

不要滥用三元运算符来做这类事情。它使得调试几乎不可能进行。为什么不做类似的事情

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

或者只是一些连锁的 if/then/else

if ($province == 6) {
     $Myprovince = "city-1";
} elseif ($province = ...) {
   ...
}

15
投票

有些人建议使用 switch 语句或 if/else 语句。但我会使用数组来代替,以使其更易于维护和阅读:

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

为什么?

代码最终可能会更容易管理。也许有一天你会想从数据库添加这些省到城市的映射..等等..这将很难用一堆 switch/case 语句来维护。


6
投票

最佳且最具可读性(IMO)的解决方案是通过 PHP 8 中的 match

 表达式
引入的:

$Myprovince = match ($province) { 6 => "city-1", 7 => "city-2", 8 => "city-3", 30 => "city-4", default => "out of borders", };
它本质上只是一个不太详细的 

switch

 语句,非常适合简单的赋值。也可以添加多个条件:

$Myprovince = match ($province) { 4, 5, 6 => "city-1", 7, 9, 10 => "city-2", 8 => "city-3", 30 => "city-4", default => "out of borders", };
    

3
投票
尝试添加更多括号:

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

您的代码存在三元运算符优先级问题。

但我认为你真的应该放弃这个运算符并尝试使用

switch

 来代替。


3
投票
我认为在 PHP 中编写嵌套三元运算符的更可读的方式是这样的:

$myprovince = $province == 6 ? "city-1" : ( $province == 7 ? "city-2" : ( $province == 8 ? "city-3" : ( $province == 30 ? "city-4" : "out of borders" )));
您需要做的就是计算左括号 (

(

) 的数量,并在最后一行末尾添加相同数量的右括号 (
)
)。

另一种选择是使用单行 if/elseif/else,正如已经建议的那样 - 但是,我会像这样直观地格式化它们,以提高可读性:

if ($province == 6) $myprovince = "city-1"; elseif ($province == 7) $myprovince = "city-2"; elseif ($province == 8) $myprovince = "city-3"; elseif ($province == 30) $myprovince = "city-4"; else $myprovince = "out of borders";
    

2
投票
我今天也遇到了同样的问题。其他人已经给出了可接受的解决方案。我的只是强调一个衬垫如果。我认为更具可读性。

if ($province == 6) $Myprovince = 'city-1'; elseif ($province == 7) $Myprovince = 'city-2'; elseif ($province == 8) $Myprovince = 'city-3'; elseif ($province == 30) $Myprovince = 'city-4'; else $Myprovince = 'out of borders';
    

1
投票
使用开关代替。 三元运算符确实不应该用于多个条件,因为它们很快就会变得非常难以理解。

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'; }
    
© www.soinside.com 2019 - 2024. All rights reserved.