The null operators: ?? and ?:
A program does not always have a value. A variable may never have been set, or it may hold null, "no value". Then you need a default: "guest" instead of a name, five instead of a limit.
Let's go back to the two cashiers. A customer hands over a discount coupon. The lenient cashier treats any coupon with nothing much written on it as empty: a zero, an empty string. The strict one applies the default discount only when there is no coupon at all.
In PHP the strict cashier here is ??, and the lenient one is ?:.
<?php
$discount = null;
echo $discount ?? 5, "\n"; // 5
echo $coupon ?? 'none', "\n"; // none
$discount = 0;
echo $discount ?? 5, "\n"; // 0
echo $discount ?: 5, "\n"; // 5Let's go through the program line by line:
$discount ?? 5prints5:$discountholdsnull.$coupon ?? 'none'printsnone: there is no variable$couponat all, and PHP gives no warning.- After
$discount = 0the expression$discount ?? 5prints0: zero is a real value, notnull. $discount ?: 5prints5: for?:zero counts as empty.
The ?? operator
The null coalescing operator is written $a ?? $b:
- if
$ais set and is notnull, the result is$a; - otherwise the result is
$b.
?? first checks whether the variable exists and only then reads it. That is why it stays silent on a variable that was never set, although a plain read of $coupon would give Warning: Undefined variable $coupon.
A chain of ??
You can put ?? operators one after another: $a ?? $b ?? 'x'. PHP checks from left to right and takes the first value that is set and is not null. If $a and $b are both null, the result is 'x'.
The ??= operator
$limit ??= 20 writes 20 into $limit only if the variable is not set or is null:
$limit = null;
$limit ??= 20;
$page = 0;
$page ??= 1;
echo $limit, ' ', $page, "\n"; // 20 0$limit now holds 20, while $page stays 0: zero is set and is not null.
The ?: operator
$a ?: $b takes $b when $a turns into false. Among the values you know so far, these turn into false:
falseandnull;0and0.0;- the empty string
''and the string'0'.
These are the same values that (bool) turns into false. For ?: an empty string in $name means "no name", so $name ?: 'guest' gives guest.
But ?: reads the variable as usual. If it was never set, PHP gives a warning, as with any read of a variable that was never set.
Interviewers often ask how ?? differs from ?:. The answer:
??replaces onlynulland a variable that was never set, and it does so without a warning;?:replaces everything that turns intofalse, including0and'';?:reads the variable as usual, and a variable that was never set gives aWarning.
The cashier picture simplifies here. A real cashier will ask what you meant, but ?: does not ask: to it zero is always empty, even when it is an honest price of zero. When 0 or '' are valid values, use ??.
Common mistake
A default name is supplied with ?:, but nobody set the variable:
echo $nickname ?: 'guest', "\n"; // ✗Warning: Undefined variable $nicknamePHP prints the warning and then guest: ?: reads $nickname as an ordinary variable, and it does not exist. The program keeps running, but the warning points to a bug in the code. Replace ?: with ??: $nickname ?? 'guest' prints guest without a warning.
Key points
??supplies the right side when the left one is missing or holdsnull, and it gives no warning.?:supplies the right side for everything that turns intofalse:0,'','0',null.$x ??= 20writes20only if$xis not set or isnull.- When zero or an empty string is a valid value, choose
??.