PHP 7 and the Null Coalescing Operator ??

Coming from C#, one my favorite additions to that language was null coalescing operator. I’m happy to say that PHP 7 has added this operator and it’s a great operator that can make your code more clear and purposeful.

Would you like to coalesce?

The word coalesce according to one dictionary is a verb that means “come together to form one mass or whole: the puddles had coalesced into shallow streams.” And now, I suddenly have found myself thinking of corny pickup lines you might hear at nerdy parties. Let’s put that aside for a moment. It programming parlance, when you coalesce two values, only one returns. However, this isn’t a But make no mistake, this is not the product, sum, or result of two inputs. Many enter… but only one exits. It’s a death match of inputs where only on remains. Well, not quite… but you get the point.

Two wrestlers coalescing…

How can you Coalesce in PHP ??

The null coalescing operator ( ?? ) in PHP is essentially syntactic sugar for the isset() function. Let’s imagine a scenario where you have a form that asks for a person’s first and last name for a flight booking engine. Most flight engines require both a first and last name for a ticket, however not all people have both. In places like Brazil, Turkey, Iceland, Indonesia, etc. it’s quite common to be mononymous and only have one name. On airline tickets, you’ll see their name written twice, like PÉLÉ PÉLÉ or BJÖRK BJÖRK. So if you have a form asking for their name and they only enter first name you want to repeat that for the last name. The following two code examples have identical results:

// use isset()
if (isset( $_GET['lname'] )
  $last_name = $_GET['lname'];
else {
  $last_name = $_GET['fname'];
}
// using the null coalescing operator
$last_name = $_GET['lname'] ?? $_GET['fname'];

I don’t know about you, but I find the second way far more readable and elegant than the first. If your code can closely resemble a natural language sentence, it’s a huge win in my book. In the first example:

If lname is set, then set <em>last_name</em> to equal lname, otherwise set <em>last_name</em> to equal fname.

Compare that to:

Set <em>last_name</em> to <em>lname</em> [maybe? or…] <em>fname</em>.

That’s a pretty simple example, but what about a more complicated example. What if you needed several fall backs. Let’s say you want to set directions and you allow a preference of using either km or miles. If the user has entered a preference, you want to use that, but if they don’t then if you know the user’s country’s standard use that, otherwise fallback to a system default. You could either do a bunch of isset statements, a switch...case block or just this:

$distance_unit = $user->unit ?? $user->country->unit ?? 'km';

That’s pretty elegant if you ask me. And much cleaner and readable than:

if( isset( $user->unit ) ) {
  $distance_unit = $user->unit;
}
else if ( isset($user->country->unit ) ) {
  $distance_unit = $user->country->unit;
}
else {
  $distance_unit = 'km';
}

Not only is that 9 lines of code instead of 1, there’s a whole lot of repetition and room for typos.

What about the ternary operator?

If you’re unfamiliar with the ternary operator, I’d recommend looking it up, but in summary, it’s shorthand way of writing an if/else statement. Here’s a quick example, using our lname / fname scenarios above:

//
// $variable = (conditional) ? (is true) : ( is false )
//
$last_name = isset( $_GET['lname'] ) ? $_GET['lname'] : $_GET['fname'];

It’s also one line of code, like the null coalescing operator, but it’s also harder to read. It’s also NOT a substitute for the null coalescing operator. Because it’s a substitute for an if/else statement, it will evaluate falsey values, like 0 and “” as false, but if a variable does NOT exist, it will return a warning. So if you removed the isset() function above, PHP will throw a warning. It also evaluates the statements twice: Once to check the value, and again to retrieve it. The ternary operator is best used for scnarioes where you have a true/false value and you want to provide one of two options:

$passenger_class = ($age > 18) ? 'adult' : 'child'; 

Another area where ternary operators fall flat is chaining. Imaging our

$passenger_class = $age < 5 ? 'toddler' : ( $age < 13 ? 'child' : ($age < 18 ? 'teenager' : 'adult' ));

Not only is that hard to read, it’s super easy to make a mistake. In those cases, use a switch statement or just good old if/else blocks. You’ll thank yourself 6 months from now when you have to look at the code again.

If we used our example above of choosing a unit of measure for distance, imagine that if/else block written with ternary operators:

$distance_unit = isset($user->unit) ? $user->unit : ( isset($user->country->unit ) ? $user->country->unit : 'km' ) );

Yuck!

In the end, ?? is a nice bit of syntactic sugar that acts as a wrapper for the isset() function. Using it can make your code more readable and more readable code is better code. It’s different from a ternary operator, as ternary operators are more flexible and really you should check if a variable exists using isset() first.

(featured image by Gerd Altmann from Pixabay)

Leave a Reply

Your email address will not be published. Required fields are marked *