← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Null Coalescing Operator (??)

php PHP 7.0+ Beginner
debt(d3/e1/b3/t5)
d3 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'default linter catches the common case' (d3). The detection_hints list phpcs, rector, and php-cs-fixer — all standard PHP linting/fixers — which can catch the isset() ternary pattern not using ?? and flag ?? vs ?: confusion. This is a common-case catch by default tooling.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1). The quick_fix explicitly states replacing isset($a) ? $a : $default with $a ?? $default — a single-expression substitution. Rector can automate this transformation across the codebase, making it trivial per occurrence.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The operator applies broadly across web, cli, and queue-worker contexts, but misuse (confusing ?? with ?:) is confined to the specific expression site. It imposes a per-developer learning cost but doesn't structurally shape the codebase or slow down many work streams.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5). The misconception field explicitly identifies that ?? and ?: are NOT interchangeable: falsy non-null values like 0, '', or false behave differently between the two operators. This is a documented gotcha (common_mistakes confirms it as the top mistake) that most PHP developers eventually learn, but it's not obvious from the operator's name or appearance.

About DEBT scoring →

Also Known As

?? operator null coalescing operator PHP 7 null coalescing

TL;DR

Returns the left operand if it exists and is not null, otherwise the right — cleaner than isset() ternary chains.

Explanation

$value = $_GET['key'] ?? 'default' is equivalent to isset($_GET['key']) ? $_GET['key'] : 'default'. The ?? operator suppresses undefined index notices and handles null in one step. The ??= assignment operator (PHP 7.4) sets a variable only if it is null: $config['debug'] ??= false. Prefer ?? over empty() when you want to distinguish between a missing value and a legitimately empty/zero value — empty() treats 0, "0", [], and "" as falsy, which is often not what you want.

Common Misconception

?? and ?: (ternary shorthand) are interchangeable. ?: returns the left operand if it is truthy; ?? returns the left operand if it is not null. These differ for falsy non-null values: 0 ?? "default" returns 0 but 0 ?: "default" returns "default".

Why It Matters

The null coalescing operator (??) replaces verbose isset() ternaries with a concise, readable fallback expression. It prevents undefined index notices and makes default-value patterns clear at a glance.

Common Mistakes

  • Confusing ?? with ?: (Elvis) — ?? checks for null/undefined, ?: checks for falsiness (0, '', false also trigger it).
  • Chaining too many ?? operators in a line — more than two or three becomes unreadable, extract a variable.
  • Using ??= and expecting it to work on non-null falsy values — it only assigns when the left side is null.
  • Relying on ?? to suppress all errors — it only handles null and undefined keys, not type errors or exceptions.

Code Examples

✗ Vulnerable
// Verbose null check:
$name = isset($user['name']) ? $user['name'] : 'Guest';
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;

// Null coalescing — concise:
$name = $user['name'] ?? 'Guest';
$page = (int)($_GET['page'] ?? 1);

// Null coalescing assignment (PHP 7.4):
$config['timeout'] ??= 30; // Only assigns if null or not set
✓ Fixed
// ?? — returns left side if not null, otherwise right side
$name = $user['name'] ?? 'Guest';

// Chains — first non-null wins
$locale = $user->locale ?? $account->locale ?? config('app.locale');

// ??= — assign if null (PHP 7.4)
$_SESSION['cart'] ??= [];
$_SESSION['cart'][] = $item;

// Nested arrays — no need for isset() checks
$city = $data['user']['address']['city'] ?? 'Unknown';

Added 15 Mar 2026
Edited 22 Mar 2026
Views 28
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Amazonbot 8 Perplexity 5 Unknown AI 3 Ahrefs 2 SEMrush 2 Google 1 Bing 1
crawler 21 pre-tracking 1
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Replace isset($a) ? $a : $default with $a ?? $default; replace $obj->method() ?? $default with null-safe operator $obj?->method() ?? $default
📦 Applies To
PHP 7.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
isset($var) ? $var : $fallback pattern not using ?? operator
Auto-detectable: ✓ Yes phpcs rector php-cs-fixer
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✓ Auto-fixable Fix: Low Context: Line

✓ schema.org compliant