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

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

我正在为 laravel 应用程序使用 PHP 7.4,但我经常收到此异常。

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] : '';
}

能帮我解决这个问题吗?

发现这是 E_DEPRECATED 由于 PHP 中的某些升级而导致的错误,但是有什么方法可以 通过将已弃用的代码转换为最新的 [=22] 来解决此异常=]?

在你的情况下,你应该使用 ?? instead of isset and ternaries:

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

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',
)

作为您脚本的人类reader,我会假设您的条件是从左到右的读取——但这会将 Spanish1 作为输出值。

甚至在php7.4之前,输出都是Spanish2,因为决策树中的后者fork优先。

为避免这种情况,您必须将条件括在括号中以准确指示应如何处理执行顺序。

另外,我同意@Laurel 的观点,在 php7 中,您是时候接受 null 合并运算符的语法甜头了。这将避免优先级问题和使用括号的需要,但根据您想要的结果,您可能需要重新排序您的条件。

$values 的优先级:(Demo)

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

$filesContent 的优先级:(Demo)

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

P.s。 IIRC,php 手册基于代码清晰度建议不要像这样使用嵌套的 ternaries/conditionals。我不介意这种情况,我喜欢避免代码膨胀,但其他开发人员可能会采取更纯粹的立场。

您需要在代码两边添加括号:

之前:

$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');

这应该可以解决问题。