Question
PHP Elvis Operator (?:) vs Null Coalescing Operator (??)
Question
In PHP, what is the difference between the short ternary operator (?:) and the null coalescing operator (??)?
When do these two expressions behave differently, and when do they produce the same result?
$a ?: $b
$a ?? $b
Short Answer
By the end of this page, you will understand how PHP's short ternary operator ?: and null coalescing operator ?? decide whether to return the left or right value. You will learn the key difference between falsy checks and null-or-undefined checks, see where they behave the same, and know which one to choose in real PHP code.
Concept
The two operators look similar, but they solve different problems.
?:is the short ternary operator, often called the Elvis operator.??is the null coalescing operator.
Their difference comes from what they test.
?: checks for truthiness
$result = $a ?: $b;
This means:
$result = $a ? $a : $b;
So PHP evaluates $a as a boolean.
If $a is truthy, the result is $a.
If $a is falsy, the result is $b.
In PHP, common falsy values include:
false0
Mental Model
Think of the two operators as two different gatekeepers.
?: is a strict "does this look usable?" gatekeeper
It looks at the value and says:
- "If this is truthy, keep it."
- "If this is falsy, replace it."
So values like 0 or "" get rejected, even if they are meaningful.
?? is a "is anything actually missing?" gatekeeper
It asks:
- "Is there a value here?"
- "Is it not null?"
If the answer is yes, it keeps the value, even if that value is 0, false, or "".
Simple analogy
Imagine filling out a form:
?:says: "This field looks empty or weak, so I will use the backup."??says: "I only use the backup if the field was not filled in at all, or was explicitly null."
That is the core difference: falsy vs missing/null.
Syntax and Examples
Core syntax
$a ?: $b
$a ?? $b
Expanded forms
$a ?: $b // same as: $a ? $a : $b
$a ?? $b // similar to: isset($a) ? $a : $b
Example 1: value is 0
$a = 0;
$b = 100;
echo $a ?: $b; // 100
echo "\n";
echo $a ?? $b; // 0
Why?
0is falsy, so?:returns$b0is not null, so??returns
Step by Step Execution
Consider this code:
$a = 0;
$b = 5;
$x = $a ?: $b;
$y = $a ?? $b;
Step-by-step for $x = $a ?: $b;
- PHP reads
$a. - PHP converts
$ato a boolean for the condition. $ais0, which is falsy.- Because the condition is false, PHP returns
$b. $xbecomes5.
Step-by-step for $y = $a ?? $b;
- PHP checks whether
$ais set and notnull. $aexists.$ais0, not .
Real World Use Cases
Use ?? for optional input and defaults
Request parameters
$page = $_GET['page'] ?? 1;
$search = $_GET['search'] ?? '';
This is useful because the key may not exist at all.
Configuration values
$host = $config['host'] ?? 'localhost';
$port = $config['port'] ?? 3306;
If the config key is missing or null, a default is used.
Nested data access
$username = $user['profile']['username'] ?? 'guest';
Use ?: when any falsy value should trigger a fallback
Display label fallback
Real Codebase Usage
In real PHP projects, developers often use these operators in predictable patterns.
Pattern: safe defaults from arrays and request data
$sort = $_GET['sort'] ?? 'created_at';
$limit = $_GET['limit'] ?? 20;
This avoids notices for missing keys and keeps valid falsy values if they exist.
Pattern: environment and configuration fallback
$env = $_ENV['APP_ENV'] ?? 'production';
$debug = $config['debug'] ?? false;
This is common in framework bootstrapping and config loading.
Pattern: normalize output after processing
$title = trim($title) ?: 'Untitled';
After transforming data, ?: is useful when an empty result should be replaced.
Pattern: guard clause with defaults
{
?? ;
}
Common Mistakes
Mistake 1: using ?: when 0 is a valid value
$quantity = 0;
echo $quantity ?: 10; // 10
If 0 is a meaningful value, this is wrong.
Better
echo $quantity ?? 10; // 0
Mistake 2: using ?: with false when false is a real setting
$enabled = false;
$result = $enabled ?: true; // true
This overwrites a valid false value.
Better
$result = ?? ;
Comparisons
| Operator | What it checks | Returns right side when left side is... | Preserves 0 | Preserves false | Preserves "" | Safe for undefined variable |
|---|---|---|---|---|---|---|
?: | Truthiness | falsy | No | No | No | No |
?? | isset()-style null check | undefined or null | Yes | Yes | Yes | Yes |
Cheat Sheet
$a ?: $b // uses $b if $a is falsy
$a ?? $b // uses $b if $a is undefined or null
Use ?: when
- you want to reject all falsy values
- empty strings should fall back
0andfalseshould also fall back
Use ?? when
- a variable or array key may be missing
nullshould trigger the default0,false, and""are valid values
Falsy values in PHP
These make ?: choose the right side:
false00.0"""0"
FAQ
What is the difference between ?: and ?? in PHP?
?: checks whether the left value is truthy. ?? checks whether the left value exists and is not null.
Does ?? behave like isset()?
Yes. a ?? b is roughly equivalent to isset($a) ? $a : $b.
Does ?: treat 0 as empty?
Yes. Since 0 is falsy in PHP, ?: will use the fallback value.
When do ?: and ?? return the same result?
They return the same result when the left side is null.
Which operator should I use for $_GET or $_POST values?
Usually , because request keys may be missing and values like or may still be valid.
Mini Project
Description
Build a small PHP script that reads optional user settings and displays final values with sensible defaults. This project demonstrates the practical difference between ?: and ?? when handling missing data, empty strings, zero values, and boolean flags.
Goal
Create a script that shows when to preserve valid falsy values with ?? and when to replace empty-style values with ?:.
Requirements
- Create variables representing optional settings such as username, page number, and dark mode.
- Use
??for values that may be missing or null. - Use
?:for a display value where an empty string should fall back. - Print the final resolved values so the difference is visible.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.