New in PHP 7: null coalesce operator

Not the catchiest name for an operator, but PHP 7 brings in the rather handy null coalesce so I thought I'd share an example.

In PHP 5, we already have a ternary operator, which tests a value, and then returns the second element if that returns true and the third if it doesn't:

echo $count ? $count : 10; // outputs 10

There is also a shorthand for that which allows you to skip the second element if it's the same as the first one:

echo $count ?: 10; // also outputs 10

In PHP 7 we additionally get the ?? operator which rather than indicating extreme confusion which is how I would usually use two question marks together instead allows us to chain together a string of values. Reading from left to right, the first value which exists and is not null is the value that will be returned.

// $a is not set
$b = 16;

echo $a ?? 2; // outputs 2
echo $a ?? $b ?? 7; // outputs 16

This construct is useful for giving priority to one or more values coming perhaps from user input or existing configuration, and safely falling back on a given default if that configuration is missing. It's kind of a small feature but it's one that I know I'll be using as soon as my applications upgrade to PHP 7.

23 thoughts on “New in PHP 7: null coalesce operator

  1. Thanks for this post - I had heard about the null coalesce operator (and have had several instances this past week when I wished I had it available already) but the ternary shorthand was new to me!

  2. Pingback: New in PHP 7: null coalesce operator | PHP Information

  3. Could you explain this? You say "Reading from right to left, the first value which exists and is not null is the value that will be returned.", but then you have this snippet:

    echo $a ?? $b ?? 7; // outputs 16

    I'd interpret your text as: start with 7. It exists, and is not null, so that value is returned. But it isn't? Should the output be 7, or should the text be "left to right" ?

    • I had issues understanding it myself, but then again it makes sense.
      The ?? operator returns the "left-hand" operand if it is not null.

      $b = 16;

      $b ?? 7

      Since the "left-hand" operand is not null 16 is returned, then after this,
      we then evaluate the following

      $a ?? 16
      and as a result 16 is returned because the left-hand operand is null..

  4. Shouldn't that be 'Reading from left to right', instead of the other way around?

    Thanks for explaining this usefull new operator. I would have probably glansed over it when reading about it in a list of new features!

  5. I've used null coalesce in MySQL before, but it will be nice to have it in PHP. I didn't know about that shorthand version of the ternary operator though, thanks for mentioning that! :)

  6. Should it be reading left to right so first none null is 16 rather than right to left where the first none null would be 7 ?

  7. You are all completely correct and apparently I don't know my left from my right when I blog before coffee! I fixed it, thanks people :)

  8. I admit as well that it can be very hard to understand at first if you don't know this new syntax, but when you do it's super useful and clean and it will save you a lot of keystrokes in some cases!

    Thanks for sharing it

  9. Pingback: PHPNW15 Conference Review | Code Review Videos

  10. Pingback: PHP Annotated Monthly – October 2015 | JetBrains PhpStorm Blog

  11. Great that it doesn't seem to throw an E_NOTICE whereas the ternary does. When [code]$foo['bar'][/code] is undefined using [code]$foo['bar'] ?: ''[/code] throws an E_NOTICE forcing me to write it more verbosely like [code]isset($foo['bar']) ? $foo['bar'] : ''[/code]. Now I can just use [code]$foo['bar'] ?? ''[/code]

  12. Pingback: November 2015 Newsletter - Nomad PHP

  13. Pingback: Laravel 5.5 will require PHP 7.0+ -

  14. Pingback: Checking if isset and is true? - ExceptionsHub

  15. After uses for a while, this is just a potential bugger. Because it checks NULL and NULL value only. This is just not classic PHP. If you love what PHP does with if($var).... then you know what I mean. NULL is not covering empty string. So return $a??$b??$c??$d; if $b is empty string, it will be returned without checking $c and $d any more.

    We have $a?:$b?:$c?:$d already, which are checking TRUE and it is very PHP. Less is more.