NullCoalescingOperatorCanBeUsed
info on by default quick-fix PHP ≥ 7.0Group: Language level migration · PhpStorm name: NullCoalescingOperatorCanBeUsedInspection
Ternaries and small if constructs that pick a value when it "exists" (isset, !== null, array_key_exists, truthiness of the owning object) and a fallback otherwise can be collapsed into a single ?? expression, which is shorter and easier to read.
Example
php
<?php
class Box {
/** @var int */
public $size;
/** @var Box|null */
public $inner;
}
/** @var Box $box */
/** @var Box[] $boxes */
$a = isset($opts['k']) ? $opts['k'] : 5;
$b = !isset($opts['k']) ? null : $opts['k'];
$c = null === $row->id ? $fallback . 'x' : $row->id;
$d = (array_key_exists($k, $map)) ? $map[$k] : NULL;
$e = $box ? $box->size : 0;
$f = !$box ? null : $box->inner;
$g = !empty($boxes[1]) ? $boxes[1]->size : null;
$h = $box ? $box->inner : -1; // nullable with non-null fallback
$i = $mystery ? $mystery->size : null; // unknown type
$j = array_key_exists($k, $map) ? $map[$k] : 0;
$k2 = isset($opts['k'], $opts['j']) ? $opts['k'] : 5;
$l = isset($opts['k']) ?: 5;
function pickA($in) {
$out = 'none';
if (isset($in['v'])) {
$out = $in['v'];
}
$n = abs($n);
if (isset($in[$n])) { $n = $in[$n]; } // previous value reads the target
if ($in['w'] !== null) {
return $in['w'];
}
return 'none';
}
function pickB($in) {
if ($in) {
$res = 1;
} else if (isset($in)) {
$res = $in;
} else {
$res = 2;
}
if (!(null === $in)) {
return $in;
} else {
return null;
}
}
$cb = function ($q) {
if (isset($q)) {
return $q;
}
};php
<?php
class Box {
/** @var int */
public $size;
/** @var Box|null */
public $inner;
}
/** @var Box $box */
/** @var Box[] $boxes */
$a = $opts['k'] ?? 5;
$b = $opts['k'] ?? null;
$c = $row->id ?? ($fallback . 'x');
$d = $map[$k] ?? NULL;
$e = $box->size ?? 0;
$f = $box->inner ?? null;
$g = $boxes[1]->size ?? null;
$h = $box ? $box->inner : -1; // nullable with non-null fallback
$i = $mystery ? $mystery->size : null; // unknown type
$j = array_key_exists($k, $map) ? $map[$k] : 0;
$k2 = isset($opts['k'], $opts['j']) ? $opts['k'] : 5;
$l = isset($opts['k']) ?: 5;
function pickA($in) {
$out = $in['v'] ?? 'none';
$n = abs($n);
if (isset($in[$n])) { $n = $in[$n]; } // previous value reads the target
return $in['w'] ?? 'none';
}
function pickB($in) {
if ($in) {
$res = 1;
} else { $res = $in ?? 2; }
return $in ?? null;
}
$cb = function ($q) {
return $q ?? null;
};Reported:
- line 11: Simplify to '$opts['k'] ?? 5' using the null coalescing operator.
- line 12: Simplify to '$opts['k'] ?? null' using the null coalescing operator.
- line 13: Simplify to '$row->id ?? ($fallback . 'x')' using the null coalescing operator.
- line 14: Simplify to '$map[$k] ?? null' using the null coalescing operator.
- line 15: Simplify to '$box->size ?? 0' using the null coalescing operator.
- line 16: Simplify to '$box->inner ?? null' using the null coalescing operator.
- line 17: Simplify to '$boxes[1]->size ?? null' using the null coalescing operator.
- line 26: Simplify to '$out = $in['v'] ?? 'none'' using the null coalescing operator.
- line 31: Simplify to 'return $in['w'] ?? 'none'' using the null coalescing operator.
- line 40: Simplify to '$res = $in ?? 2' using the null coalescing operator.
- line 45: Simplify to 'return $in ?? null' using the null coalescing operator.
- line 53: Simplify to 'return $q ?? null' using the null coalescing operator.
Options
| Option | Type | Default | Effect |
|---|---|---|---|
| SUGGEST_SIMPLIFYING_TERNARIES | bool | true | Enables Form A (ternaries). |
| SUGGEST_SIMPLIFYING_IFS | bool | true | Enables Form B (if statements). |
Both upstream fixtures set only one option explicitly, but the other one keeps its default true, so both forms are active in both runs.
Configure
In custos.json:
json
{
"rules": {
"NullCoalescingOperatorCanBeUsed": {
"enabled": false,
"options": {
"SUGGEST_SIMPLIFYING_TERNARIES": true,
"SUGGEST_SIMPLIFYING_IFS": true
}
}
}
}Suppress
Before the statement or declaration (or the first statement of the file), either of:
php
// @custos-ignore NullCoalescingOperatorCanBeUsed
/**
* @noinspection NullCoalescingOperatorCanBeUsedInspection
*/