4

I have read that PHP isset and null coalescing operator used to ignore PHP Notice: Undefined index:

I have seen this post also PHP ternary operator vs null coalescing operator

But I am getting PHP notice with both of them while using them with string concatenation operator:

<?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
?>

EDIT:

I know This can be solved by the following methods

1) assigning to variable like

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

2) using @

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

3) adding brackets (and as Karsten suggested )

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

But I am looking for the reason behind it.

Rohit Dhiman
  • 2,691
  • 18
  • 33
  • 1
    use brackets around `("sgadjgjsd".$array['c'])`. Operator `.` [has higher precedence than the terniary](http://php.net/manual/en/language.operators.precedence.php) – Karsten Koop Nov 28 '18 at 12:20
  • Thank you @KarstenKoop for your reply, but I am looking for the reason behind it. – Rohit Dhiman Nov 28 '18 at 12:22
  • 3
    because you concatenate before the ternary comes into effect, so the notice is from the concatenation – Karsten Koop Nov 28 '18 at 12:24

2 Answers2

11

Every operator has its own 'importance' (operator precedence, as @Karsten-koop pointed out) which dictates in what order they are executed. For example:

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

In this case:

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

PHP will do the following steps:

  1. Concatenate (.) the string sgadjgjsd with the value of $array['c'].
  2. $array['c'] does not exist, so a notice is emitted.
  3. The end result (sgadjgjsd) is then run through the null coalescing operator, and since the string is not equal to null, the string is returned (not '').
  4. The end result is assigned to a variable named $val.

So why does 10 + 5 * 3 equal 25? Look up the * and + operators in the table on the linked page. Notice that * is higher up in the list, so it goes first.
For the other example, the concatenation opereator . is (quite a bit) higher up than ??.

Using brackets is the proper solution; they allow you to specify what goes first:

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

Side-note: You might recognise this same concept from school because the same thing exists in mathematics (some historical background on why).

RickN
  • 12,537
  • 4
  • 24
  • 28
0

This is because you want to concatenate a string with a null in first case and in second case with boolean value

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

will not gonna throw any error but concatenating total different data type with different one will throw error.