PHP错误:未加括号的`a ? b : c ? d : e`已弃用。请使用`(a ? b : c) ? d : e`或`a ? b : (c ? d : e)`。

14

我正在使用PHP 7.4为laravel应用程序,并经常遇到这个异常。

ErrorException (E_DEPRECATED)
Unparenthesized `a ? b : c ? d : e` is deprecated. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)`

引发此异常的代码是:

foreach ($allLanguages as $languageKey) {
    $original[$languageKey] =
        isset($values[$languageKey])
            ? $values[$languageKey]
            : isset($filesContent[$fileName][$languageKey][$key]) ? $filesContent[$fileName][$languageKey][$key] : '';
}

有人能帮我解决这个问题吗?

发现这是由于PHP的一些升级而导致的E_DEPRECATED错误,但是否有办法通过将弃用的代码转换为最新版本来解决此异常?


3
在你想要对它们进行分组的地方添加括号。 - Progman
3
这绝对是 PHP 生成的较不难懂的错误信息之一。 - mickmackusa
3个回答

12

你需要在代码周围添加括号:

之前的代码:

$reference->frotel_vitrine = empty($item->special) ? null : $item->special == 2 || $item->special == 3 ? 'active' : 'deactivate';

之后:

$reference->frotel_vitrine = empty($item->special) ? null : (($item->special == 2 || $item->special == 3 )? 'active' : 'deactivate');

这应该解决了这个问题。


10

这个PHP的更改是为了消除决策树中的歧义,以便明确条件执行的顺序。

以下是弃用警告:

代码:

$allLanguages = ['en', 'es', 'fr'];
$values = ['es' => 'Spanish1'];
$filesContent = [
    'foo' => [
        'es' => ['bar' => 'Spanish2'],
        'fr' => ['bar' => 'French']
    ]
];
$fileName = 'foo';
$key = 'bar';

$original = [];
foreach ($allLanguages as $languageKey) {
    $original[$languageKey] =
        isset($values[$languageKey])
            ? $values[$languageKey]
            : isset($filesContent[$fileName][$languageKey][$key])
                ? $filesContent[$fileName][$languageKey][$key]
                : '';
}
var_export($original);

输出:

Deprecated: Unparenthesized `a ? b : c ? d : e` is deprecated. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)` in /in/TG4g2 on line 17
array (
  'en' => '',
  'es' => 'Spanish2',
  'fr' => 'French',
)
作为你脚本的人类读者,我会假设对你的条件进行从左到右的阅读--但这将把Spanish1作为输出值。 即使在php7.4之前,输出也是Spanish2,因为决策树中后者的分叉具有优先权。 为避免此问题,您必须使用括号将条件包装起来,以精确地指定执行顺序应如何处理。 另外,我同意@Laurel的观点,在php7中,你应该拥抱那些语法甜蜜的空值合并运算符。它将避免优先级问题和使用括号的需要,但根据您所需的结果,您可能需要重新排序您的条件。 给$values优先级:(演示)
$original[$languageKey] =
    $values[$languageKey]
        ?? $filesContent[$fileName][$languageKey][$key]
            ?? '';

将优先使用$filesContent:(演示)

$original[$languageKey] =
    $filesContent[$fileName][$languageKey][$key]
        ?? $values[$languageKey]
            ?? '';

顺便说一句,如果我没记错的话,php手册建议不要使用嵌套的三元运算符/条件语句,原因是代码阅读性不好。我个人并不介意这种情况,而且我喜欢避免代码臃肿,但其他开发人员可能会持更为纯粹的立场。


它正在显示已弃用的内容,但我们如何知道它何时会产生致命错误,以便在特定日期之前给予一些时间来纠正该代码? - Bhavin Thummar
“它显示已弃用”,那么开始修复你的项目的时间是:现在。 - mickmackusa
谢谢你的回答。你知道是哪个PHP版本生成了这个警告吗? - Bhavin Thummar
1
我简直不敢相信!语言语法已经过时了!PHP是对人类的真正罪行! - Ahmad
1
$d = $a ? $d : ("'" === $d[0] ? $d : "'$d'"); - mickmackusa
显示剩余4条评论

3
在您的情况下,应该使用 ?? 而不是 isset 和三目运算符
foreach ($allLanguages as $languageKey) {
    $original[$languageKey] = $values[$languageKey]??  $filesContent[$fileName][$languageKey][$key] ?? '';
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,