8

Php 8.0 introduced the nullsafe operator which can be used like so $foo?->bar?->baz;. I have a code sample running on php 8.1 that throws the error Undefined property: stdClass::$first_name even though it is using the nullsafe operator:

$reference = (object) $reference; // Cast of array to object

return [
    'FirstName' => $reference?->first_name,
];

To solve the error, I have to use the null coalescing operator:

$reference = (object) $reference; // Cast of array to object

return [
    'FirstName' => $reference->first_name ?? null,
];

Why is the nullsafe operator throwing an error in this case?

Don't Panic
  • 41,125
  • 10
  • 61
  • 80
naghal
  • 537
  • 3
  • 19

2 Answers2

9

You seem to have a slight misunderstanding of what the nullsafe operator does.

If $reference was null, then $reference?->first_name would return null with no warning, but since $reference is actually an object, ?-> just functions like a normal object operator, hence the undefined property warning.

Don't Panic
  • 41,125
  • 10
  • 61
  • 80
  • So how are you supposed to do it when you have a reference chain where the first object definitely exists? e.g. $exists->maybe->also_maybe ? – joachim Jan 31 '23 at 11:28
  • 1
    Basically, this operator only comes into play if the the left-hand side is `null`. If the `$exists` object is set, but has no `maybe` property, then `$exists->maybe`, will produce the same issue the question is asking about where the nullsafe operator isn't really useful. If the `maybe` property _is_ present, but might have a null value, then the nullsafe operator could be used after it to prevent a warning when trying to read `also_maybe`, or anything else chained after that. If you don't know whether the first property in the chain exists or not, it's probably better to use `??` instead. – Don't Panic Jan 31 '23 at 16:12
0

You can use a try-catch in case you have many nested properties:

try {
    if ($response->foo->bar->foo->bar->status == 'something') {
        ...
    }
} catch (\ErrorException $ex) {
    // Property missing exception will be caught here
}
the_nuts
  • 5,634
  • 1
  • 36
  • 68