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

Mac*_*lor 33 php operators ternary-operator

这就是我写的:

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

但是对于每个领域我都有价值city-4.我想使用三元运算符而不是switch/if因为我想要实验并看看它将如何完成.

这段代码有什么问题?

cod*_*ict 89

其他人已经提出了正确的方法,但如果你真的想使用三元运算符,你需要使用括号:

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

更新链接

  • *不寒而栗*为了打字,我会给你的勇气+1,但不能让自己"认可"这样一个可怕的事情...... (23认同)
  • 绝对保证+1坚持不懈 (4认同)
  • @Mac Taylor:您使用的工具错误。没什么可说的了。您还可以使用字符串串联'a'。'b'。'c'`创建字符串''abc'`,但是为什么这样做呢?祝您在三元野兽中添加一个新城市充满乐趣,别忘了数一下以匹配括号! (2认同)
  • 我认为拒绝使用链式三元作为编程模式并不是一个好的回应.它使得许多语言中的简洁清晰的代码"正确地"实现它,并且因为它生成**表达式**,有时它是快速修复某些东西的唯一方法.我使用了引号,因为虽然PHP设计人员确实做出了asinine选择,使其三元运算符左关联,但事实已经充分记录. (2认同)

Fel*_*ing 33

三元运算符从左到右进行评估.因此,如果您没有正确分组表达式,您将得到意外的结果.

PHP的建议是[docs]:

建议您避免"堆叠"三元表达式.PHP在单个语句中使用多个三元运算符时的行为是不明显的.

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

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

它应该在哪里

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

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


你最好用这样的东西:

$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];
}
Run Code Online (Sandbox Code Playgroud)

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

$Myprovince = isset($map[$province]) ? $map[$province] : 'out of borders';
Run Code Online (Sandbox Code Playgroud)

  • 请注意,PHP 8 已禁用没有显式括号的嵌套三元组。 (3认同)
  • 用它来缩短它:`$ Myprovince = isset($ map [$ province])?$ map [$ province]:'out of borders';`;-) (2认同)

Mar*_*c B 17

不要滥用三元运算符来做这类事情.它使调试几乎无法遵循.为什么不做类似的事情

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

或者只是一些链接if/then/else

if ($province == 6) {
     $Myprovince = "city-1";
} elseif ($province = ...) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

  • @Mac Taylor:不,你没有.是什么原因?朦胧? (4认同)
  • 三元对这些的最大好处是它允许具有单个变量分配。 (3认同)

arn*_*rhs 12

有些人建议使用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';
Run Code Online (Sandbox Code Playgroud)

为什么?

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

  • 我会像你一样。绝对是最佳答案! (2认同)

Noa*_*oah 5

我知道这是一个关于 PHP 的问题,但由于这只是一个教育练习,我认为您可能有兴趣了解 Ruby 和 Javascript 实际上的行为方式是否符合您的预期。

红宝石:

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"
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)