Skip to content
Advertisement

Difference between PHP ??, ?:, and ??=

Something I’m not exactly clear on, how does ??, ?:, and ??= differ in PHP?

I know ??= was only added in PHP7.4. I also know that ?? is for checking null values, but ?: also seems to check for null values, so I’m not entirely sure of the difference.

Advertisement

Answer

To combine all answers already made in former questions. With ?? you check for existence and not being null, with ?: you check for true/false.

$result = $a ?? $b

is the same as:

if (isset($a) && !is_null($a)) {
    $result = $a;
} else {
    $result = $b;
}

The ??= is a shortcut for ?? and it works like .= or += as well, which means you can shorten

$a = $a ?? $b;

to

$a ??= $b;

The ?: is a shortcut for the ternary operator which is also a shortcut:

if ($a) {
    $result = $a;
} else {
    $result = $b;
}

is the same as:

$result = $a ? $a : $b;

is the same as:

$result = $a ?: $b;

You could both describe as: The first operand is the value to check, and if this one is useful, take it, if not, take the second as default.

You can concatenate them like this one:

$user = $_POST['user'] ?? $_SESSION['user'] ?? $_COOKIE['user'] ?? '';

Which means something like: If you get the username in the POST array because of just logging in, fine, take it, if not, see whether the user is already logged on and in the session, if yes, take it, if not, maybe we have a user in the Cookies (checked the “remember me” checkbox while last login), and if this fails also, well, then leave it empty.

Of course you have to check the password too. 😉

Edit: I use the ?: operator very often to ensure that I have a certain datatype in a variable. There are a lot PHP functions that give back maybe a string or an array if successful, but false if some error occured. Instead of having false as result, having the empty string or empty array is more consistent. As example, scandir should give back an array, but gives back false if an error occures. So you can do this:

$files = scandir('/some/random/folder') ?: [];

Then $files will always be an array, even if scandir fails. Well, then it’s an empty array, but maybe better than checking later against false. In fact, we already did it with very low effort. Then you can use a foreach loop without some wrapping if. If scandir failed, the array is empty and the loop will just do nothing.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement