4

If I am loading a model with Model::find($id) and the id is not found it returns null.

This is fine except if I try to chain things.

Model::find($id)->loadAttributes();

Load attributes is going to fail because it's not a method of null.

The simple solution break it into two lines and check if it's null before calling loadAttributes or doing a try/catch but I'm curious if there's another solution I'm not thinking of.

Matt
  • 185
  • 1
  • 8
  • 1
    Make the find method return a NullModel object if it doesn't find anything and override loadAttribute so it throws an exception. Stop checking for null, really, this is so easy to forget especially when everything works fine at the time of development. – Steve Chamaillard Sep 23 '16 at 18:17

1 Answers1

2

If you can't do method chaining, don't do method chaining.

$model = Model::find($id);
if ($model === null) {
  ... // handle error
}

$model->loadAttributes();

That's probably the least error prone way to do this. If the null-case is to be expected in the normal course of operation, you should not use the exception system to handle this.

PHP 7 adds a null coalescing operator ??, but not a null-propagating method call operator (e.g. ?. in C#). With such an operator, a call $a?->b() might be equivalent to $a === null ? $a->b() : null.

One idiom you might sometimes see is assigning the variable inside the condition:

if (($model = Model::find($id)) !== null) {
  $model->loadAttributes();
} else {
  ... // handle error
}

This style makes more sense in other languages where this would also restrict the scope of the assigned variable to the conditional, and when there is no error handling – if the return value is null, there's nothing to do.

amon
  • 132,749
  • 27
  • 279
  • 375