What's The Difference Between ?? And ?: In PHP?

A comparison and analysis of the Null Coalescing and Evlis/Shorthand Ternary Operator in PHP

  • By Daniyal Hamid
  • June 17, 2019
  • Comments
In This Article

In this article, we'll compare and analyze the two shorthand conditional operators in PHP, the shorthand ternary operator, i.e. the evlis operator (?:), and the null coalescing operator (??).

?: (Elvis Operator)

Since PHP 5.3+, we can use the shorter ternary operator syntax by leaving out the middle part of the ternary operator for a quick shorthand evaluation:

expr1 ?: expr2;

This shorthand syntax is also referred to as the elvis operator (?:). Note that the following statements are equivalent:

// using the elvis operator
expr1 ?: expr2;

// using the ternary operator
expr1 ? expr1 : expr2;

// using if/else
if (expr1) {
    return expr1;
} else {
    return expr2;
}

The statements above translate to; if expr1 evaluates to true, return expr1, otherwise return expr2.

If a falsy value is encountered, the evlis operator will return the second operand. Or, if a truthy value is encountered, the first operand (i.e. the truthy value) is returned. Note, however, that when the left hand side of the elvis operator evaluates to true, the right hand side of the expression is not evaluated. This is because of short-circuiting, which means the second operand is executed or evaluated only if the first operand does not evaluate to true.

It is important to remember that the following values are considered false in PHP:

  • Boolean false;
  • Integer 0;
  • Float 0.0;
  • String '0' or "0";
  • An empty string (i.e. '' or "");
  • An empty array (i.e. [] or array());
  • null;
  • SimpleXML objects created from empty tags.

Note that the strings "00", "0.0", "\0", and "false" all evaluate to boolean true which is different from string '0' or boolean false.

Ternary Chaining:

The ternaries can be chained (i.e. it returns the first truthy value it encounters), for example:

echo 0 ?: 1 ?: 2 ?: 3; // output: 1

This is the same as writing a series of if/elseif/else statements, for example:

if (expr1) {
    return expr1;
} else if(expr2) {
    return expr2;
} else if(expr3) {
    return expr3;
} else {
    return expr4;
}

Similarities With Other Languages:

In certain programming languages (such as Perl, Python, Ruby, and JavaScript), the elvis operator is written as the OR operator (typically || or or). This has the same behavior, i.e. returning its first operand if it evaluates to true, or evaluating and returning its second operand otherwise.

?? (Null Coalescing Operator)

Introduced in PHP 7, the null coalescing operator (??) has the following syntax:

expr1 ?? expr2;

Which means that expr1 is returned when expr1 exists and is NOT null; otherwise it returns expr2. This is the same as the following:

// as an if statement:
if (isset($x)) {
    return $x;
} else {
    return $y;
}

// or, as ternary operator:
return (isset($x) ? $x : $y);

// same statement as the null coalescing operator:
return $x ?? $y;

For a null coalescing operator, the only thing that matters is that the variable exists and is not null so even falsy values are given a pass.

Coalescing Chaining:

The coalescing can be chained (i.e. it returns the first defined value it encounters), for example:

$x ?? $y ?? $z ?? 'empty'; // output: 'empty'

In case there's no defined value in the coalescing chain, a "Notice: Undefined variable: ..." message is shown.

?: Vs. ??

The table below shows a side-by-side comparison of the two operators against a given expression:

Expression echo ($x ?: 'hello') echo ($x ?? 'hello')
$x = ""; 'hello' ""
$x = null; 'hello' 'hello'
$x; 'hello'
(and Notice: Undefined variable: x)
'hello'
$x = []; 'hello' []
$x = ['a', 'b']; ['a', 'b'] ['a', 'b']
$x = false; 'hello' false
$x = true; true true
$x = 1; 1 1
$x = 0; 'hello' 0
$x = -1; -1 -1
$x = '1'; '1' '1'
$x = '0'; 'hello' '0'
$x = '-1'; '-1' '-1'
$x = 'random'; 'random' 'random'
$x = new stdClass; object(stdClass) object(stdClass)