16

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?

1

3 Answers 3

17

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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

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
}

1 Comment

Writing a try-catch block on every object property access would leave most professional scripts in a horrifically bloated state.
1

In your case you will need to check both $reference and $reference->first_name for null. Thus the proper solution would be:

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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.