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

Null Coalescing ?? Operator (PHP 7.0)

php PHP 7.0+ Beginner
debt(d3/e1/b1/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 rector and phpcs with an automated code_pattern `isset\([^)]+\)\s*\?`, meaning the common misuse (verbose isset ternary instead of ??) is caught by standard linting/sniffing tools without specialist configuration.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1). The quick_fix is explicit: replace `isset($x)?$x:$default` with `$x??$default`. This is a mechanical, single-expression substitution with no multi-file impact.

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

Closest to 'minimal commitment' (b1). The ?? operator is a local, expression-level syntactic choice. It imposes no structural debt on the codebase; each use is self-contained and its adoption or non-adoption doesn't shape the system's architecture or slow other work streams.

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

Closest to 'notable trap' (t5). The misconception field states exactly this trap: developers confuse ?? with ?:, not realising ?? only checks null/unset while ?: checks truthiness, meaning '' and 0 behave differently between the two. This is a documented gotcha (common_mistakes confirm it) that many PHP developers encounter, but it is a known, single-dimension distinction rather than a systemic contradiction.

About DEBT scoring →

TL;DR

PHP 7.0's ?? operator returns the left side if it exists and isn't null, otherwise the right — replacing isset($x) ? $x : $default with $x ?? $default.

Explanation

$a ?? $b returns $a if isset($a) and not null, else $b. PHP 7.4 added ??= (null coalescing assignment): $a ??= 'default' sets $a to 'default' if $a is null/unset. Chaining: $a ?? $b ?? $c ?? 'final'. Key behaviour: ?? doesn't suppress E_NOTICE for array access ($arr['key'] ?? null — no notice), unlike the ternary. Works with array nesting: $config['db']['host'] ?? 'localhost'. Compared to ?: (Elvis operator): ?: checks truthiness (falsy empty string triggers fallback); ?? checks null/unset only.

Common Misconception

?? is the same as ?: — ?? checks for null/unset only ('' and 0 are kept), ?: checks truthiness ('' and 0 trigger the fallback).

Why It Matters

?? replaces the most common verbose PHP pattern (isset() ternary) with a clean, readable operator that handles missing array keys without notices.

Common Mistakes

  • Using ?: when 0 or '' should be preserved — use ?? instead.
  • Not knowing $arr['missing'] ?? null suppresses the undefined key notice.
  • Not using ??= for lazy initialization.

Code Examples

✗ Vulnerable
$name = isset($user['name']) ? $user['name'] : 'Guest';
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
✓ Fixed
$name = $user['name'] ?? 'Guest';
$page = (int)($_GET['page'] ?? 1);

// PHP 7.4 assignment:
$cache ??= $this->loadFromDb();

// Chaining:
$host = $config['db']['host'] ?? $env['DB_HOST'] ?? 'localhost';

Added 23 Mar 2026
Views 18
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 1 ping S 2 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F
No pings yesterday
Amazonbot 7 Unknown AI 3 Google 3 Perplexity 2 ChatGPT 1 Ahrefs 1 Bing 1
crawler 15 crawler_json 2 pre-tracking 1
DEV INTEL Tools & Severity
🔵 Info ⚙ Fix effort: Low
⚡ Quick Fix
Replace isset($x)?$x:$default with $x??$default. Replace isset($x)?$x:$x=$default with $x??=$default (PHP 7.4). Chain with ?? for multiple fallbacks.
📦 Applies To
PHP 7.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
isset\([^)]+\)\s*\?
Auto-detectable: ✓ Yes rector phpcs
🤖 AI Agent
Confidence: High False Positives: Low ✓ Auto-fixable Fix: Low Context: Line

✓ schema.org compliant