Home » Php » Shorthand ternary operator PHP – Call to a member function on null

Shorthand ternary operator PHP – Call to a member function on null

Posted by: admin February 25, 2020 Leave a comment

Questions:

Given the class:

<?php
class foo {
    public function getGuest() {
        return new guest();
    }
}

class guest {
    public function getGender() {
        return 'F';
    }
}

I wanted to refactor the following which works fine:

$bar->getGuest() ? $bar->getGuest()->getGender() : NULL

To:

$bar->getGuest() ?: $bar->getGuest()->getGender()

Where I get the error: Call to a member function getGender() on null

I was expecting this to work in the same fashion as the top version, as it was my understanding that the second version was, if the left hand side is truthy, return the left-hand, otherwise return the right-hand. So if the left-hand is falsey, why is the right-hand running? Can someone explain this?

Given the second version doesn’t work, is the top version the most concise?

How to&Answers:

From the PHP manual:

Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.

Let’s look at what you’re trying to do here:

$bar->getGuest() ?: $bar->getGuest()->getGender()

The way this works is if the first $bar->getGuest() expression equals true, your operation will return the value of $bar->getGuest() itself. This should work fine, no errors.

However, if $bar->getGuest() returns something else (e.g. null) it will run the third expression, which is $bar->getGuest()->getGender().

Well we already established that $bar->getGuest() returned null, so how can you then go and run another method ->getGender() on the null value? You can’t, which is why you are getting the error.


There’s nothing wrong with keeping your code readable and simple. You probably want to store the initial method call value, so you don’t have to call it again just to run getGender().

$guest = $bar->getGuest();
$gender = ($guest === null) ? null : $guest->getGender();