The ternary operator is an if/else that fits in one expression: condition ? valueIfTrue : valueIfFalse. It returns one of the two values, so you can assign it, echo it or pass it to a function.
Change $age to 15 and $items to 3 and run it again. Note the parentheses around the ternary in the last line: without them the . would join the strings first and the result would not be what you want.
Ternary in HTML templates
A ternary is the usual way to pick a CSS class, a label or an attribute inside a template. This block reads ?stock= from the URL: run it, then click the links in the Page tab and the same script runs again with a different value.
<?= ... ?> is short for <?php echo ... ?>, which keeps one-line conditions readable inside markup.
Short ternary ?: (the Elvis operator)
Leave out the middle part and you get $a ?: $b: it returns $a when $a is truthy, otherwise $b. It is handy for defaults when an empty string or 0 should also fall back.
Falsy values are false, 0, 0.0, "", "0", [] and null. If "0" is a real answer in your data (a quantity field, a PIN), the short ternary will throw it away.
?: vs ??
They look alike but check different things. ?: falls back when the left side is falsy. ?? falls back only when the left side is null or not set, and it does not warn about a missing variable or array key.
Use ?? for "the value might not exist" (request data, config arrays, optional keys). Use ?: for "the value exists but might be empty". The null coalescing operator page covers ?? and ??= in detail.
Nested ternary needs parentheses
PHP 7 read a ? b : c ? d : e from left to right, unlike almost every other language, and it produced wrong results. PHP 8 refuses to guess:
<?php
echo $score > 90 ? "A" : $score > 80 ? "B" : "C";
PHP Fatal error: Unparenthesized `a ? b : c ? d : e` is not supported. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)` in /home/index.php on line 2
Add parentheses around the inner ternary and it works:
The short ternary is the exception: $a ?: $b ?: $c is allowed without parentheses, as in the Elvis example above.
Use match(true) when there are more than two branches
A nested ternary with three or four levels is hard to read even with parentheses. match with true as the subject checks conditions from top to bottom and returns the first matching arm:
Keep the ternary for two outcomes on one line, and reach for match or an if/elseif chain as soon as you need a third.
Frequently Asked Questions
What is the ternary operator in PHP?
A short form of if/else that returns a value: $label = $age >= 18 ? 'adult' : 'minor';. If the condition before ? is true, the expression after ? is used, otherwise the one after :.
What does ?: mean in PHP?
$a ?: $b is the short ternary (also called the Elvis operator). It returns $a if $a is truthy and $b otherwise, so '' ?: 'default' is 'default'. It is the same as $a ? $a : $b, but $a is evaluated only once.
Can you nest ternary operators in PHP?
Only with parentheses. Since PHP 8, $a ? 'x' : $b ? 'y' : 'z' is a fatal error, so write $a ? 'x' : ($b ? 'y' : 'z'). For more than two branches, match(true) or an if/elseif chain is easier to read.
Can I use a ternary without the else part?
No, the ternary always needs both branches. For "use this value or fall back" write $x ?: 'default' or $x ?? 'default'; to only do something when a condition holds, write a normal if or $condition && doSomething();.