【问题标题】:Is this a bug in PHP null coalesce operator or expected behaviour?这是 PHP 空合并运算符中的错误还是预期行为?
【发布时间】:2019-08-11 14:45:42
【问题描述】:

我偶然发现了一个 if 语句,它使用 PHP 的 null coalesce 运算符,表现得不像“预期的”。有问题的代码如下所示:

if ($foo['bar'] ?? false || $foo['baz'] ?? false) { /* ... */ }

改成

if (($foo['bar'] ?? false) || ($foo['baz'] ?? false)) { /* ... */ }

解决了。

我在终端中进行了快速测试:

root@docker:/application# php -v
PHP 7.2.11-2+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Oct 15 2018 11:40:35) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.11-2+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies
    with Xdebug v2.6.1, Copyright (c) 2002-2018, by Derick Rethans
root@docker:/application# php -a
Interactive mode enabled

php > $test = ['foo' => 'bar'];
php > var_dump($test['baz'] ?? null); // as expected
php shell code:1:
NULL
php > var_dump(($test['baz'] ?? null)); // as expected
php shell code:1:
NULL
php > var_dump($test['baz'] ?? null || $test['foobar'] ?? null); // as expected, but there's a Notice
PHP Notice:  Undefined index: foobar in php shell code on line 1
PHP Stack trace:
PHP   1. {main}() php shell code:0
php shell code:1:
bool(false)
php > var_dump(($test['baz'] ?? null) || ($test['foobar'] ?? null)); // as expected
php shell code:1:
bool(false)

现在,我认为在测试号中会发生什么。 3,是它被执行为

$test['baz'] ?? (null || $test['foobar']) ?? null

因此,如果 $test['baz'] 评估为未设置(显然是这样),则下一个 null || $test['foobar'] 将被执行,这将导致 $test['foobar'] 抛出通知。

我的问题:这是 PHP 中 null 合并运算符的预期行为吗?我有点期望它比||(或)运算符绑定得更强。
另一方面,在 RFC (https://wiki.php.net/rfc/isset_ternary) 中有一个明确的例子:

var_dump(0 || 2 ?? 3 ? 4 : 5); // ((0 || 2) ?? 3) ? 4 : 5 => int(4)

这可能表明,上面的例子是正确的行为。

你怎么看?这应该被报告为错误吗?我知道这不是一个“正确”的问题,但是由于我找不到关于它的错误报告/讨论/线程,我认为应该有一个资源来记录它。
如果你/模组不同意,我会再次删除问题。

【问题讨论】:

  • 如果 RFC 确认该行为,为什么会是错误?
  • 这不只是operator precedence|| 的优先级高于 ??
  • @PatrickQ 它并不能完全确认这种行为,但 IMO 也有类似的情况。这就是我问的原因。
  • 我认为没有必要回答。这更像是一个 RTM 案例。
  • @Barmar IMO,这里的很多问题应该因此而消失。但话又说回来,我不同意这里的全新理念,即为内容而内容。

标签: php null-coalescing-operator


【解决方案1】:

这是由于operator precedence 而导致的预期行为

|| 的优先级高于??,因此您的原始语句被视为

if ($foo['bar'] ?? (false || $foo['baz']) ?? false)

【讨论】:

    猜你喜欢
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 2015-07-25
    相关资源
    最近更新 更多