嵌套三元语句

发布于 2024-12-08 07:51:19 字数 517 浏览 0 评论 0原文

我想知道为什么这会很奇怪。我知道区别在于分组,但是比较重要吗?

$i = 0;
foreach ($items as $item) {
   echo ($i == 0) ? 'first_row' : ($i == sizeof($feedbacks)-2) ? 'last_row' : 'none';
   $i++;
}

返回

last_row
none
none
last_row

$i = 0;
foreach ($items as $item) {
   echo ($i == 0) ? 'first_row' : (($i == sizeof($feedbacks)-2) ? 'last_row' : 'none');
   $i++;
}

正确返回

first_row
none
none
last_row

为什么有区别?

I wonder why this works strange. I understand that the difference is grouping, but does it matter in comparison?

$i = 0;
foreach ($items as $item) {
   echo ($i == 0) ? 'first_row' : ($i == sizeof($feedbacks)-2) ? 'last_row' : 'none';
   $i++;
}

returns

last_row
none
none
last_row

and

$i = 0;
foreach ($items as $item) {
   echo ($i == 0) ? 'first_row' : (($i == sizeof($feedbacks)-2) ? 'last_row' : 'none');
   $i++;
}

returns it correctly

first_row
none
none
last_row

Why is there a difference?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

吃素的狼 2024-12-15 07:51:19

要使用基于您的代码的解释,缩小版本将是:

for ($i=0; $i<5; $i++) {
   echo $i == 0 ? 'first_row' : $i == 4 ? 'last_row' : 'none';
}

在 PHP 中,这相当于编写:

for ($i=0; $i<5; $i++) {
   echo ($i == 0 ? 'first_row' : $i == 4) ? 'last_row' : 'none';
}

第一次,$i 的值为 0,因此第一个三元数返回 'first_row' 并且该字符串用作第二个三元数的条件 - 在布尔上下文中计算结果为 true - 因此 'last_row' 返回。

如果重新组合:

for ($i=0; $i<5; $i++) {
   echo $i == 0 ? 'first_row' : ($i == 4 ? 'last_row' : 'none');
}

那么第一个三元的结果不会干扰第二个三元。

To use an explanation based on your code, a scaled down version would be:

for ($i=0; $i<5; $i++) {
   echo $i == 0 ? 'first_row' : $i == 4 ? 'last_row' : 'none';
}

In PHP, this is equivalent to writing:

for ($i=0; $i<5; $i++) {
   echo ($i == 0 ? 'first_row' : $i == 4) ? 'last_row' : 'none';
}

On the first go, $i has the value of 0, so the first ternary returns 'first_row' and that string is used as the conditional for the second ternary -- which in boolean context evaluates to true -- hence 'last_row' is returned.

If you regroup it:

for ($i=0; $i<5; $i++) {
   echo $i == 0 ? 'first_row' : ($i == 4 ? 'last_row' : 'none');
}

then the result of the first ternary will not interfere with the second ternary.

清风无影 2024-12-15 07:51:19

来自官方 PHP 文档 :

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

显然,即使 PHP 的三元运算符(及其大部分语法)基于 C ,出于某种原因,PHP 决定使其左关联,然而在 C 和基于它的大多数其他语言中,三元运算符是右结合的:

C:

$ cat /tmp/foo.c
#include <stdio.h>
void main (void) { printf("%s\n", ( 1 ? "foo" : 0 ? "bar" : "baz" ) ); }

$ gcc -o /tmp/foo /tmp/foo.c; /tmp/foo
foo

Perl:

$ perl -e 'print ( 1 ? "foo" : 0 ? "bar" : "baz" ) . "\n";'
foo

Java:

$ cat /tmp/foo.java
public class foo { public static void main(String[] args) {
    System.out.println( ( true ? "foo" : false ? "bar" : "baz" ) );
} }

$ javac -d /tmp /tmp/foo.java; java -cp /tmp foo
foo

JavaScript:

$ cat /tmp/foo.js
print( 1 ? "foo" : 0 ? "bar" : "baz" );

$ rhino -f /tmp/foo.js
foo

PHP:

$ php -r 'echo ( 1 ? "foo" : 0 ? "bar" : "baz" ) . "\n";'
bar

所以,是的,我认为我们可以有把握地得出这样的结论:PHP 在这方面(也)只是简单的倒退。

From the official PHP documentation:

"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"

Apparently, even though PHP's ternary operator (and much of its syntax otherwise) is based on C, for some reason PHP decided to make it left-associative, whereas in C and most other languages based on it, the ternary operator is right-associative:

C:

$ cat /tmp/foo.c
#include <stdio.h>
void main (void) { printf("%s\n", ( 1 ? "foo" : 0 ? "bar" : "baz" ) ); }

$ gcc -o /tmp/foo /tmp/foo.c; /tmp/foo
foo

Perl:

$ perl -e 'print ( 1 ? "foo" : 0 ? "bar" : "baz" ) . "\n";'
foo

Java:

$ cat /tmp/foo.java
public class foo { public static void main(String[] args) {
    System.out.println( ( true ? "foo" : false ? "bar" : "baz" ) );
} }

$ javac -d /tmp /tmp/foo.java; java -cp /tmp foo
foo

JavaScript:

$ cat /tmp/foo.js
print( 1 ? "foo" : 0 ? "bar" : "baz" );

$ rhino -f /tmp/foo.js
foo

PHP:

$ php -r 'echo ( 1 ? "foo" : 0 ? "bar" : "baz" ) . "\n";'
bar

So, yeah, I think we can safely conclude that PHP is just plain ass-backwards in (also) this respect.

涫野音 2024-12-15 07:51:19

请参阅 php.net 上的示例 3

<?php
// on first glance, the following appears to output 'true'
echo (true?'true':false?'t':'f');

// however, the actual output of the above is 't'
// this is because ternary expressions are evaluated from left to right

// the following is a more obvious version of the same code as above
echo ((true ? 'true' : false) ? 't' : 'f');

// here, you can see that the first expression is evaluated to 'true', which
// in turn evaluates to (bool)true, thus returning the true branch of the
// second ternary expression.
?>

重要的部分是:

这是因为三元表达式是从左到右计算的

See example 3 on php.net:

<?php
// on first glance, the following appears to output 'true'
echo (true?'true':false?'t':'f');

// however, the actual output of the above is 't'
// this is because ternary expressions are evaluated from left to right

// the following is a more obvious version of the same code as above
echo ((true ? 'true' : false) ? 't' : 'f');

// here, you can see that the first expression is evaluated to 'true', which
// in turn evaluates to (bool)true, thus returning the true branch of the
// second ternary expression.
?>

The important part being:

this is because ternary expressions are evaluated from left to right

风轻花落早 2024-12-15 07:51:19

看看JRL提供的答案。为了更清楚地了解您的示例发生的情况,您应该了解您的表达式是这样计算的:

echo (($i == 0) ? 'first_row' : ($i == sizeof($feedbacks)-2)) ? 'last_row' : 'none';

因此,当 $i == 0 时,您的语句基本上变成这样:

echo 'first_row' ? 'last_row' : 'none';

Since 'first_row'< /code> 计算结果为 true,您的 'last_row'$i == 0 时返回的结果。当 $i 不等于 0 时,你的语句基本上变成这样:

echo ($i == sizeof($feedbacks)-2) ? 'last_row' : 'none';

Take a look at the answer provided by JRL. To be more clear about what is happening with your example you should understand that your expression is evaluated as such:

echo (($i == 0) ? 'first_row' : ($i == sizeof($feedbacks)-2)) ? 'last_row' : 'none';

So when $i == 0 your statement essentially becomes this:

echo 'first_row' ? 'last_row' : 'none';

Since 'first_row' evaluates to true your 'last_row' is the result returned when $i == 0. When $i does not equal zero your statement essentially becomes this:

echo ($i == sizeof($feedbacks)-2) ? 'last_row' : 'none';
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文