为什么 PHP isset 和 Null 合并运算符使用串联运算符抛出通知?

Why PHP isset and Null coalescing operator is throwing Notice with concatenation operator?

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

我也看过这个post

但是我在将它们与字符串连接运算符一起使用时收到了 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'] ?? '');

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

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

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

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

每个运算符都有自己的 'importance'(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?在链接页面的 table 中查找 *+ 运算符。请注意 * 在列表中的位置较高,因此排在第一位。
对于另一个示例,串联运算符 .??.

高(相当多)

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

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)。