Viewed   96 times

I saw this today in some PHP code:

$items = $items ?: $this->_handle->result('next', $this->_result, $this);

I'm not familiar with the ?: operator being used here. It looks like a ternary operator, but the expression to evaluate to if the predicate is true has been omitted. What does it mean?

 Answers

2

It evaluates to the left operand if the left operand is truthy, and the right operand otherwise.

In pseudocode,

foo = bar ?: baz;

roughly resolves to

foo = bar ? bar : baz;

or

if (bar) {
    foo = bar;
} else {
    foo = baz;
}

with the difference that bar will only be evaluated once.

You can also use this to do a "self-check" of foo as demonstrated in the code example you posted:

foo = foo ?: bar;

This will assign bar to foo if foo is null or falsey, else it will leave foo unchanged.

Some more examples:

<?php
    var_dump(5 ?: 0); // 5
    var_dump(false ?: 0); // 0
    var_dump(null ?: 'foo'); // 'foo'
    var_dump(true ?: 123); // true
    var_dump('rock' ?: 'roll'); // 'rock'
?>

By the way, it's called the Elvis operator.

Thursday, October 6, 2022
1

The basics:

  1. An assignment expression results in the assigned value.

    What does that mean? $foo = 'bar' is an expression, in which the assignment operator = assigns a value. An expression always returns a value itself. Just like the expression 1 + 2 results in the value 3, the expression $foo = 'bar' results in the value 'bar'. That's why this works:

    $foo = $bar = 'baz'; // which is: $foo = ($bar = 'baz');
    
  2. Boolean operations are short-circuiting operations. Both sides are not always evaluated if they don't need to be. true || false is always true overall, since the lefthand operand is true, so the whole expression must be true. false is not even being evaluated here.

  3. Operator precedence dictates in which order parts of an expression are grouped into sub-expressions. Higher precedence operators are grouped with their operands before lower precedence operators.

Therefore:

$e = false || true;

false || true is being evaluated, which results in the value true, which is assigned to $e. The || operator has a higher precedence than =, therefore false || true is grouped into an expression (as opposed to ($e = false) || true).

$f = false or true;

Here now or has a lower precedence than =, which means the assignment operation is grouped into one expression before or. So first the $f = false expression is evaluated, the result of which is false (see above). So then you have the simple expression false or true which is evaluated next and results in true, but which nobody cares about.

The evaluation works like this:

1. $f = false or true;
2. ($f = false) or true;  // precedence grouping
3. false or true;         // evaluation of left side ($f is now false)
4. true;                  // result

Now:

$foo or $foo = 5; 

Here, again, $foo = 5 has a higher precedence and is treated as one expression. Since it occurs on the right side of the or operator, the expression is only evaluated if necessary. It depends on what $foo is initially. If $foo is true, the right hand side will not be evaluated at all, since true or ($foo = 5) must be true overall. If $foo has a falsey value initially though, the right hand side is evaluated and 5 is assigned to $foo, which results in 5, which is true-ish, which means the overall expression is true, which nobody cares about.

1. $foo or $foo = 5;
2. $foo or ($foo = 5);   // precedence grouping
3. false or ($foo = 5);  // evaluation of left side
4. false or 5;           // evaluation of right side ($foo is now 5)
5. true;                 // result
Tuesday, September 13, 2022
 
4

It is recommended that you avoid "stacking" ternary expressions. PHP's behaviour when using more than one ternary operator within a single statement is non-obvious

From the PHP Manual under "Non-obvious Ternary Behaviour".

Ternary operators are evaluated left to right, so unless you add it the braces it doesn't behave as you expect. The following would work though,

return (true ? "a" : (false ? "b" : "c"));
Tuesday, August 2, 2022
 
2

The

(condition) ? /* value to return if condition is true */ 
            : /* value to return if condition is false */ ;

syntax is not a "shorthand if" operator (the ? is called the conditional operator) because you cannot execute code in the same manner as if you did:

if (condition) {
    /* condition is true, do something like echo */
}
else {
    /* condition is false, do something else */
}

In your example, you are executing the echo statement when the $address is not empty. You can't do this the same way with the conditional operator. What you can do however, is echo the result of the conditional operator:

echo empty($address['street2']) ? "Street2 is empty!" : $address['street2'];

and this will display "Street is empty!" if it is empty, otherwise it will display the street2 address.

Sunday, November 13, 2022
 
4

?: is a form of the conditional operator which was previously available only as:

expr ? val_if_true : val_if_false

In 5.3 it's possible to leave out the middle part, e.g. expr ?: val_if_false which is equivalent to:

expr ? expr : val_if_false

From the manual:

Since PHP 5.3, it is possible to leave out the middle part of the conditional operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.

Thursday, November 3, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :