Of late, I have been doing some maintenance work on a legacy website which uses Laravel and PHP 7 (work on the upgrade is in progress). In testing, we found a situation where we were trying to call a method on a NULL
value. The line of code read as follows: $fleet = Chapter::find($this->getAssignedShip())->getAssignedFleet(true);
The code would then go on to properly use the $fleet
value, checking for whether or not it was NULL
before using it.
While it certainly is a beneficial design pattern, it does need some care when being used. In this case, we are tempted to do the line of code without protection, but must realize that it can fail with a fatal error, because the ::find()
method failure path is to return NULL
. Because the NULL
pointer dereference is a fatal runtime error and not an exception, we cannot use try/catch
blocks, but must do something like the following:
$chapter = Chapter::find($this->getAssignedShip());
$fleet = null;
if (!is_null($chapter)) {
$fleet = $chapter->getAssignedFleet(true);
}
Fortunately, with PHP 8.0, a new NULL-safe ?->
operator has been added, and the code becomes the following:
$fleet = Chapter::find($this->getAssignedShip())?->getAssignedFleet(true);
If :find()
returns a null, the new operator shortcuts the execution and returns null.
I will also note that this is not just a problem with PHP. You can get similar errors in C, C++, JavaScript, Python (by attempting to dereference None
), and others.