Understanding ?: vs ?? in PHP: The Clear, Simple Difference

When you start writing cleaner and more expressive PHP, two operators always show up:
- The Elvis operator →
?: - The Null coalescing operator →
??
They look similar… They behave differently… And using the wrong one can break your logic in very sneaky ways.
Let’s break them down the easy way.
?: — The Elvis Operator
Checks for “truthy” values.
If the left side is truthy, it returns it. If it's falsy, it returns the right side.
What does “falsy” mean in PHP?
false, 0, "0", "" (empty string), [], null, etc.
Example:
$name = ""; $result = $name ?: "Guest"; echo $result; // "Guest"
Because an empty string "" is falsy, PHP switches to "Guest".
Another example:
$count = 0; echo $count ?: 10; // Output: 10
0 is falsy → so we get 10.
?? — Null Coalescing Operator
Checks only for null. Nothing else.
If the left side is not null, it returns it. If it is null, it returns the right side.
Example:
$name = ""; $result = $name ?? "Guest"; echo $result; // ""
Empty string?
Still returned — because it's not null.
Another example:
$count = 0; echo $count ?? 10; // Output: 0
0 is NOT null → so PHP keeps it.
Real-World Example: User Input
Imagine handling an age field from an HTML form.
$age = $_POST['age'] ?? null; // Default to 18 only if age is missing (null) $finalAge = $age ?? 18; echo $finalAge;
If the user types 0, it should be accepted — ?? keeps it.
But if you use ?: accidentally:
$finalAge = $age ?: 18; echo $finalAge;
Typing 0 becomes 18, which is wrong.
Quick Summary
| Operator | Checks for | Example Behavior |
| -------- | ------------------------------------------ | ---------------- |
| ?: | Falsy values (0, "", [], false, null…) | 0 ?: 10 → 10 |
| ?? | Null only | 0 ?? 10 → 0 |
When to Use What
Use ?? when you want to check only for null.
Perfect for request data, config values, environment variables.
Use ?: when you want fallback for all falsy values.
Useful when empty or zero means “use default”.
