Null Coalescing Operator Not Used
debt(d3/e1/b1/t5)
Closest to 'default linter catches the common case' (d3). The detection_hints list rector, php-cs-fixer, and phpcs — all standard PHP linting/fixing tools that ship with rules covering the isset($x) ? $x : $default pattern. This is a well-known style pattern caught by default rulesets in these tools without specialist configuration.
Closest to 'one-line patch or single-call swap' (e1). The quick_fix states replacing isset($x) ? $x : $default with ?? is a direct, mechanical substitution. Tools like rector and php-cs-fixer can automate this at scale, making each individual fix a one-line replacement.
Closest to 'minimal commitment' (b1). This is a localised style choice affecting individual expressions. Not using ?? imposes no architectural weight, no cross-cutting burden, and no structural decay — it's a per-expression verbosity issue that doesn't shape system design or slow down future maintainers beyond minor readability friction.
Closest to 'notable trap' (t5). The misconception field explicitly states that ?? and ?: are confused as equivalent — but ?: triggers E_NOTICE for undefined variables while ?? suppresses it. This is a documented, well-known gotcha that competent developers often discover the hard way, especially when migrating from PHP 5 patterns. It's a real behavioral difference, not just style, meriting t5.
Also Known As
TL;DR
Explanation
PHP 7.0 introduced ?? which returns the left operand if it exists and is not null, otherwise the right. PHP 7.4 added ??= which assigns only if the variable is null. These replace the common isset($x) ? $x : $default pattern. The operator also works on array keys and chained access: $config['db']['host'] ?? 'localhost'. Unlike the ternary shorthand (?:), null coalescing does not trigger a notice for undefined variables.
Common Misconception
Why It Matters
Common Mistakes
- Using isset($x) ? $x : $default when $x ?? $default is available (PHP 7+).
- if (!isset($arr[$key])) $arr[$key] = []; — use $arr[$key] ??= [].
- Using ?: which triggers notices for undefined variables instead of ??.
- Forgetting ?? works on chained array access: $data['user']['name'] ?? 'Unknown'.
Code Examples
// Verbose — pre-PHP 7 style:
$name = isset($_GET['name']) ? $_GET['name'] : 'Guest';
$timeout = isset($config['timeout']) ? $config['timeout'] : 30;
$locale = isset($user) && isset($user->locale) ? $user->locale : 'en';
// Assignment:
if (!isset($cache[$key])) {
$cache[$key] = [];
}
// Clean — null coalescing:
$name = $_GET['name'] ?? 'Guest';
$timeout = $config['timeout'] ?? 30;
$locale = $user?->locale ?? 'en';
// Null coalescing assignment:
$cache[$key] ??= [];
// Chained:
$value = $request->get('x') ?? $config['x'] ?? $defaults['x'] ?? null;