在 PHP 中堆叠多个三元运算符
Posted
技术标签:
【中文标题】在 PHP 中堆叠多个三元运算符【英文标题】:Stacking Multiple Ternary Operators in PHP 【发布时间】:2021-12-30 04:27:20 【问题描述】:这是我写的:
$Myprovince = (
($province == 6) ? "city-1" :
($province == 7) ? "city-2" :
($province == 8) ? "city-3" :
($province == 30) ? "city-4" : "out of borders"
);
但是对于每个字段,我都得到了 city-4
的值。我想使用三元运算符而不是 switch/if
,因为我想试验一下,看看它是如何完成的。
这段代码有什么问题?
【问题讨论】:
您是否有理由不想只使用if / elseif
或switch
?
你需要更多的括号才能工作。按照 Marc 的建议,使用 switch
。
不推荐使用具有复杂嵌套条件的三元运算符,原因很充分......因为它们充满了问题,而且很难识别错误。你刚刚发现了这个!如果您真的知道如何使用它们,您就不会寻求帮助!那么在这种情况下为什么还要使用三元运算符呢?
在下方查看您的答案:***.com/questions/5235632/5235721#5235721
上帝,拜托,我不会在实时脚本中使用这种方法,永远不会,你现在好点了吗?只是好奇如何使用它:D
【参考方案1】:
另一个解决方案是在 php 8 中使用 the match
statement 引入的:
$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",
;
【讨论】:
【参考方案2】:我认为在 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";
【讨论】:
【参考方案3】:我今天也遇到了同样的问题。其他人已经给出了可接受的解决方案。我只是强调一个班轮如果。在我看来更具可读性。
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';
【讨论】:
这是一个比开关更清洁的解决方案。 开关很丑,是的,但最好是带有isset()
检查的查找数组——简单而干净。【参考方案4】:
其他人已经提出了正确的做法,但如果你真的想使用三元运算符,你需要使用括号:
$province = 7;
$Myprovince = (
($province == 6) ? "city-1" :
(($province == 7) ? "city-2" :
(($province == 8) ? "city-3" :
(($province == 30) ? "city-4" : "out of borders")))
);
Updated Link
【讨论】:
不寒而栗我会为你输入的勇气+1,但不能让自己“认可”这样一个可怕的事情...... 这确实是“正确”的做法。不过,我永远不会尝试这样的事情。 坚持不懈绝对值得+1 @Mac Taylor:你使用了错误的工具来完成这项工作。没有什么可说的了。您也可以使用字符串连接'a'.'b'.'c'
创建字符串'abc'
,但为什么要这样做呢?尽情享受为您的三元野兽添加新城市的乐趣,别忘了数数以匹配括号!
我认为拒绝使用链式三元作为编程模式并不是一个好的回应。它可以在多种语言中“正确”实现简洁明了的代码,并且因为它生成表达式,有时它是快速修复某些东西的唯一方法。我使用引号是因为虽然 PHP 设计者确实做出了 asinine 选择以使其三元运算符左关联,但事实是有据可查的。【参考方案5】:
三元运算符从左到右求值。所以如果你没有正确地对表达式进行分组,你会得到一个意想不到的结果。
PHP's advice is [docs]:
建议您避免“堆叠”三元表达式。在单个语句中使用多个三元运算符时 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';
【讨论】:
用这个让它更短:$Myprovince = isset($map[$province]) ? $map[$province] : 'out of borders';
;-)
@Jonah: True :D 我想我想尽可能远离三元运算符 ;)
对于您的编辑,我相信其他行是前几行的 c 语句。注意,没有分号。这几乎就是:($province == 6) ? "city-1" : ($province == 7) ? "city-2" : ($province == 8) ? "city-3" : ($province == 30) ? "city-4" : "out of borders";
@Phoenix:是的,我注意到并修复了它。我对这一切?
和:
感到非常困惑;)
请注意,PHP 8 禁用了没有显式括号的嵌套三元组。【参考方案6】:
我知道这是一个关于 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"
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"
【讨论】:
耸耸肩 ...当然Ruby和Javascript已经做到了...毕竟它们是编程语言^_^【参考方案7】:有些人建议使用 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 语句来维护。
【讨论】:
我会喜欢你的。绝对是最佳答案! 这个不错。不过要小心“内存不足”问题。【参考方案8】:尝试使用更多括号:
$Myprovince = (
($province == 6) ? "city-1" :
(($province == 7) ? "city-2" :
(($province == 8) ? "city-3" :
(($province == 30) ? "city-4" : "out of borders"
))));
您的代码存在三元运算符优先级问题。
但我认为你真的应该放弃这个运算符并尝试使用switch
。
【讨论】:
【参考方案9】:改用开关。三元运算符确实不应该用于多个条件,因为它们很快就会变得非常难以理解。
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';
【讨论】:
【参考方案10】:不要在这类事情上滥用三元运算符。它使调试几乎无法进行。为什么不做类似的事情
switch($province)
case 6: $Myprovince = "city-1"; break;
case 7: ...
或者只是一些链式 if/then/else
if ($province == 6)
$Myprovince = "city-1";
elseif ($province = ...)
...
【讨论】:
我不是说过我坚持使用三元运算符是因为某些原因吗? @Mac Taylor:不,你没有。是什么原因?默默无闻? @Felix:也许是调试受虐狂? 与这些相比,三元的最大好处是它允许进行单个变量赋值。以上是关于在 PHP 中堆叠多个三元运算符的主要内容,如果未能解决你的问题,请参考以下文章