Elvis lives: comparing short-ternary and null coalescing in PHP

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Who is Elvis and what does he have to do with PHP?

\n\n

If you've ever written in PHP, you've probably seen strange constructs in someone else's code: $name ?: 'Guest' or $name ?? 'Guest'. At first glance, they look the same. But in reality, these two operators hide completely different mechanics that can either save your code or cause trouble.

\n\n

On Stack Overflow, the question "PHP short-ternary ("Elvis") operator vs null coalescing operator" has gathered tens of thousands of views. And this is no coincidence. Developers get confused, make mistakes, and then spend a long time hunting for bugs. Let's finally figure out who is who, and stop guessing.

\n\n

In this article, we won't just list the differences. We'll look under the hood of PHP, examine real production cases, and understand when to use which operator. Let's go!

\n\n

Quick primer: what are these anyway?

\n\n

Ternary operator (classic)

\n

First, let's recall the basics. The ternary operator is a shortened form of if-else:

\n\n
$age = 20;\n$status = ($age >= 18) ? 'Adult' : 'Child';\n// $status = 'Adult'
\n\n

Simple: if the condition is true, take the first value; otherwise, take the second.

\n\n

Short-ternary (aka Elvis operator) — ?:

\n

This is a shortcut for when you are checking a variable for "truthiness" and want to use its value:

\n\n
$name = 'Alexey';\n$greeting = $name ?: 'Guest';\n// $greeting = 'Alexey'\n\n$name = '';\n$greeting = $name ?: 'Guest';\n// $greeting = 'Guest'
\n\n

It works like this: if $name evaluates to true, take $name. Otherwise, take "Guest".

\n\n

Null coalescing operator — ??

\n

It appeared in PHP 7.0 and immediately became a developer favorite:

\n\n
$name = 'Alexey';\n$greeting = $name ?? 'Guest';\n// $greeting = 'Alexey'\n\n$name = null;\n$greeting = $name ?? 'Guest';\n// $greeting = 'Guest'
\n\n

The difference from Elvis: the check is only for null, not for "falsiness" in general.

\n\n

Main difference: what is considered "empty"?

\n\n

This is where it gets interesting. Let's look at a comparison table for different $value values:

\n\n
$value = false;\necho $value ?: 'default'; // 'default' (false is "falsy")\necho $value ?? 'default'; // false (false is NOT null)\n\n$value = 0;\necho $value ?: 'default'; // 'default' (0 is "falsy")\necho $value ?? 'default'; // 0 (0 is NOT null)\n\n$value = '';\necho $value ?: 'default'; // 'default' (empty string is "falsy")\necho $value ?? 'default'; // '' (empty string is NOT null)\n\n$value = [];\necho $value ?: 'default'; // 'default' (empty array is "falsy")\necho $value ?? 'default'; // [] (empty array is NOT null)\n\n$value = '0';\necho $value ?: 'default'; // 'default' (string "0" is "falsy"!)\necho $value ?? 'default'; // '0' (string "0" is NOT null)
\n\n

See the difference? Elvis works as a truthy/falsy check, while null coalescing is a strict check for existence and difference from null.

\n\n

Under the hood: how it works at the engine level

\n\n

Let's look into the PHP source code (well, almost). If you've ever compiled PHP from source, you know that both operators are processed at the parsing stage.

\n\n

Short-ternary (?):

\n

In fact, it's syntactic sugar. $a ?: $b becomes $a ? $a : $b. But there's a nuance: PHP does not evaluate $a twice. It saves the result in a temporary variable. This is important for functions with side effects:

\n\n
function getData() {\n    echo "Function called!\\n";\n    return rand(0, 1) ? 'data' : '';\n}\n\n// Elvis calls the function ONCE\n$result = getData() ?: 'default';\n// "Function called!" — once
\n\n

If PHP evaluated $a twice,

Blogs

Book Recommendations