PHP's Null-safe operator has been a God-send for cutting down long chains of Eloquent relationships. It can multi-line abominations and transform them into simple and elegant checks which are easier for developers to read and more consistent.
However, they do have dark sides. One problem is trying to figure out if a chain in the result is null or not. While following best practices in typing can help in this situation, there is one things that (as of yet) cannot help you.
Take the following example:
// Is the request $user the trainer of the current model's owner?
if ($report->owner->linked_trainer?->trainer_id === $user->trainer_record?->id) {
return true;
}
return false;
At face value, the expression tests for something simple. The comment above is clear: Is the logged in user the trainer of the user who owns this particular model?
If the current user isn't a trainer, the first part of the right-hand expression ($user->trainer_record
) will resolve to null
. The left hand expression will be the ID of the user's current trainer. No problem!
Likewise if the owner doesn't have a trainer, the left-hand expression ($report->owner->linked_trainer
) will return null
. This is expected.
But! What if the owner doesn't have a trainer and the current user isn't a trainer:
if (null === null) {
return true;
}
return false;
Our permission check fails because null === null
. Ouch.
I'm currently not aware of a way to check for this, but it's one more thing I'm internally checking for when I do code reviews!
Do you know of a way to have PHPStan detect this and warn?
Top comments (0)