【问题标题】:Why PHP isset and Null coalescing operator is throwing Notice with concatenation operator?为什么 PHP isset 和 Null 合并运算符使用连接运算符抛出通知?
【发布时间】:2019-04-30 08:29:15
【问题描述】:

我已阅读 PHP isset 和 null 合并运算符用于忽略 PHP 注意:未定义索引:

我也看过这个帖子 PHP ternary operator vs null coalescing operator

但是在将它们与字符串连接运算符一起使用时,我得到了 PHP 通知:

<?php
    $array = ['a'=>'d'];

    $c = $array['c'] ?? '';
    $d = isset($array['c']) ? $array['c'] : '';
    $val = "sgadjgjsd".$array['c'] ?? ''; // PHP Notice:  Undefined index: c in /home/cg/root/986045/main.php on line 6
    $val2 = "sgadjgjsd".isset($array['c']) ? $array['c'] : ''; // PHP Notice:  Undefined index: c in /home/cg/root/986045/main.php on line 7
?>

编辑:

我知道这可以通过以下方法解决

1) 赋值给变量像

$val = "sgadjgjsd".$c = $array['c'] ?? '';

2) 使用@

$val = "sgadjgjsd".@$array['c'] ?? '';

3) 添加括号(正如 Karsten 建议的那样)

$val = "sgadjgjsd".($array['c'] ?? '');

但我正在寻找它背后的原因。

【问题讨论】:

  • ("sgadjgjsd".$array['c']) 周围使用方括号。运营商.has higher precedence than the terniary
  • 感谢@KarstenKoop 的回复,但我正在寻找背后的原因。
  • 因为你在三元生效之前就拼接了,所以通知来自拼接

标签: php php-7


【解决方案1】:

每个运营商都有自己的“重要性”(operator precedence,正如@Karsten-koop 指出的那样),这决定了它们的执行顺序。例如:

echo 10 + 5 * 3; // 25 (10+15), not 45 (15×3)

在这种情况下:

$val = "sgadjgjsd".$array['c'] ?? '';

PHP 将执行以下步骤:

  1. 将字符串sgadjgjsd$array['c'] 的值连接(.)。
  2. $array['c'] 不存在,因此发出通知。
  3. 最终结果 (sgadjgjsd) 然后通过 null 合并运算符运行,由于字符串不等于 null,因此返回字符串(不是 '')。
  4. 最终结果分配给名为$val的变量。

那么为什么 10 + 5 * 3 等于 25?在链接页面的表格中查找 *+ 运算符。请注意,* 在列表中较高,所以它排在第一位。
对于另一个示例,串联运算符.?? 高(相当多)。

使用括号是正确的解决方案;它们允许您指定先执行的操作:

echo (10 + 5) * 3;
$val = "sgadjgjsd".($array['c'] ?? '');
// Does ?? first and returns either the value of $array['c'] or ''
// and only then it does the string concatenation and assignment to $val.

http://php.net/manual/en/language.operators.precedence.php

旁注:您可能会在学校认识到同样的概念,因为同样的东西存在于数学中 (some historical background on why)。

【讨论】:

    【解决方案2】:

    这是因为您想在第一种情况下将字符串与 null 连接,在第二种情况下与布尔值连接

    $val = $array['c'] ?? '';
    

    不会抛出任何错误,但将不同的数据类型与不同的数据类型连接会抛出错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-23
      • 2012-04-12
      • 2023-03-07
      • 1970-01-01
      • 2021-02-16
      • 2013-06-16
      • 2023-03-18
      • 1970-01-01
      相关资源
      最近更新 更多