Are parentheses required in PSR-2 PHP ternary syntax?

Wallter picture Wallter · Oct 15, 2014 · Viewed 7.9k times · Source

Question: are parentheses required in PSR-2 PHP ternary syntax?

Looking for which (if either) of the following ternary statement's syntax is compliant with PSR-2 - I also need to be pointed to documentation or some authority link:

$error = ($error_status) ? 'Error' : 'No Error';

OR

$error = $error_status ? 'Error' : 'No Error';


Note: php.net it shows the syntax with the parentheses, but I could not find this in any of the 'official PSR-2' docs.


Conclusion

If there is no PSR-2 standard on this, which way is the most common convention?

Answer

IMSoP picture IMSoP · Oct 15, 2014

The PSR-2 standard specifically omits any opinion on operators:

There are many elements of style and practice intentionally omitted by this guide. These include but are not limited to: ... Operators and assignment

Since parentheses are used to group expressions, your example doesn't make much sense:

$error = ($error_status) ? 'Error' : 'No Error';

Here there is no meaning to surrounding a single variable in parentheses. A more complex condition might benefit from parentheses, but in most cases they would be for readability only.

A more common pattern would be to always surround the entire ternary expression:

$error = ($error_status ? 'Error' : 'No Error');

The main motivation for this is that the ternary operator in PHP has rather awkward associativity and precedence, so that using it in complex expressions often gives unexpected / unhelpful results.

A common case is string concatenation, e.g.:

$error = 'Status: ' . $error_status ? 'Error' : 'No Error';

Here the concatenation (. operator) is actually evaluated before the ternary operator, so the condition is always a non-empty string (beginning 'Status: '), and you will always get the string Error' as the result.

Parentheses are necessary to prevent this:

$error = 'Status: ' . ($error_status ? 'Error' : 'No Error');

A similar situation exists when "stacking" ternary expressions to form the equivalent of an if-elseif chain, as a mistake early in PHP's history means multiple ternary operators are evaluated in sequence left to right, rather than shortcutting the entire false branch when a condition is true.

An example from the PHP manual explains this more clearly:

// on first glance, the following appears to output 'true'
echo (true?'true':false?'t':'f');

// however, the actual output of the above is 't'
// this is because ternary expressions are evaluated from left to right

// the following is a more obvious version of the same code as above
 echo ((true ? 'true' : false) ? 't' : 'f');

 // here, you can see that the first expression is evaluated to 'true', which
 // in turn evaluates to (bool)true, thus returning the true branch of the
 // second ternary expression.