【问题标题】:PHP Error : Unparenthesized `a ? b : c ? d : e` is deprecated. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)` [duplicate]PHP错误:未加括号的`a?乙:丙? d : e` 已弃用。使用 `(a ? b : c) ? d:e`或`a? b : (c ? d : e)` [重复]
【发布时间】:2020-08-09 10:48:17
【问题描述】:

我正在将 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 错误,但有没有办法通过将已弃用的代码转换为最新的代码来解决此异常

【问题讨论】:

  • 添加括号说明您希望如何对它们进行分组。
  • 这绝对是 php 生成的不那么神秘的错误消息之一。

标签: php foreach reference deprecated isset


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    已经对 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 的优先级:(Demo)

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

    $filesContent的优先级:(Demo)

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

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

    【讨论】:

    • 请解释一下没有评论的DV。
    • 它显示已弃用但我们如何知道它何时会给出致命错误,以便我们可以在特定日期之前给一些时间来更正该代码?
    • "显示已弃用" ...那么开始修复项目的时间是:现在。
    • 感谢答案。你知道这个警告是哪个php版本产生的吗?
    • 从 PHP7.4 弃用,从 PHP8 开始是致命的。 3v4l.org/TG4g2
    【解决方案3】:

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

    之前:

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

    这应该可以解决问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-14
      • 1970-01-01
      • 2022-08-04
      • 2012-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多