Isak Berglind

Isak Berglind

?? vs ?: vs || in php

Isak Berglind • April 23, 2018

php

Have you ever been confused about what exactly these operators do? I know I’ve been, so I spent a little time to look it up. It turns out it’s quite simple really, but while i did my research, I stumbled upon som nifty tricks I didn’t know about before. This article will cover what the different operators does, what distinguishes them and some use cases for each one.

?: — Ternary

The ternary expression is basically a if else shorthand.

The following snippet:

if ($condition) {
    $name = "John";
} else {
    $name = "Jane";
}

Can be shortened to this:

$name = $condition ? "John" : "Jane";

It has more features though. If you for example want to use a variable if it evaluates truthy, or else use a default, you can write it like this:

$nameOrDefault = $name ? $name : "default";

However, it can be shortened to this:

$nameOrDefault = $name ?: "default";

A note on nesting

You can nest ternary expressions. There are a big gotcha thought! Php reads this from left to right, so it will probably evaluate it different from what you’d expect.

If you for example write this:

$name = true ? "John" : true ? "Jane" : "Jacob";

You would expect the output to be “John” right? It isn’t, it’s actually “Jane”.

Why? Because php does this behind the scenes

$name = (true ? "John" : true) ? "Jane" : "Jacob";

instead of this (as you might have thought)

$name = true ? "John" : (true ? "Jane" : "Jacob)";

This means that in the first expression — It picks “John” as expected. But then it takes the result of that first expression (which is “John”) and converts it to a boolean. A non empty string is evaluated as true in php, and therefore the result becomes “Jane”. It makes sense when you know it, right? But it can be a real pain to debug if you don´t.

In conclusion — You can totally nest, but then make sure to manually add those parentheses

?? — Null coalescing

This bad boy showed up in php 7.0.

What it allows you to do is very similar to the ternary expression

$nameOrDefault = $name ?: "default";

Except when you write it with the null coalescing operator, the $name variable can be undefined,

unset($name);
$nameOrDefault = $name ?? "default";

If you would try this with the ternary operetor, php will throw a notice

Whats even better, this works with undefined array keys and object properties too

// You can do this
$name = $notDefined["withKey"] ?? "default";

// Or this.
$name = $notDefined->withProp ?? "defualt";

// Or even this!
$name = $notDefined->withProp["withKey"] ?? "default";

And there´s more! You can even chain these expressions

$name = $maybeThis ?? $orThis ?? "default";

How cool isn’t that? :)

|| — Logical or

The logical or operator is great when you are working with booleans. It simply checks the first value, returns true if its truthy, otherwise it does the same check the second value, and so on.

$result = true || true; // true
$result = true || false; // true
$result = false || true; // true
$result = false || false; // false

You can also add more checks to the chain

$result = false || false || false || true; // true

If you were to put an expression or a function call on the right side of the operator, and the left side is evaluates to true, the right side never runs

$i = 0;
$result = true || $i++;
// $i equals 0

Conclusion

Hopefully something cleared for you reading this. Feel free to send me your thoughts, feedback or a shout-out on twitter. You’ll find me at @Isak_Berglind