Looking for which (if either) of the following ternary statement\'s syntax is compliant with PSR-2 - I
Some mixed opinions on this, and it's something that's unfortunately arbitrary.
What appears more common to me from what I’ve seen and have learned from would be best explained by noting the differences below, more specifically; how the parentheses don’t move in either case.
Long hand:
if ($is_full_page) {
echo "medium-6";
} else {
echo "medium-7";
}
Short hand:
echo ($is_full_page) ? 'medium-6' : 'medium-7';
That; to me; is true consistency in all it's beauty.
Common convention is always simplify. PSR standard goes a way that
$error = $error_status ? 'Error' : 'No Error';
Seems more cleaner than parentheses.
If you want explicit more readability, the PSR-2 standard goes to:
if ($error_status) {
$error = 'Error';
else {
$error = 'No Error';
}
It's all. PSR it's a standard to better understand our code, when you write a code like you are providing, you're going deeper on simplification, and there's no limitation to your imagination, just avoid not exceed PSR rules.
Use PHP Code Sniffer to check-out your code on PSR1 and PSR2 rules.
Code Sniffer
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.
One important thing to keep in mind is that PSR-2 states that lines SHOULD NOT be longer than 80 characters.
The ternary syntax can be pretty long sometimes, so I think we have a missing recommendation for a very common kind of code.
What I'm doing currently is indent it like this:
$stuff = $count > MyLongNamespace\MyLongClassName->get('count')
? 'yikes this seems to be some large stuff'
: 'erm this is rather small stuff';
If it's not explicitly stated, then there is no standard. Either works.