开发者

Multiple conditions in the ternary operator safe?

I have seen advice that says the ternary operator must not be nested.

I have tested the code below and it works okay. My question is, I haven't seen the ternary operator 开发者_如何学编程used like this before. So, is this as reliable as it were used in an if or could something like this come and bite me later(not in terms or readability, but by failing).

$rule1 = true;
$rule2 = false;
$rule3 = true;

$res = (($rule1 == true) && ($rule2 == false) && ($rule3 == true)) ? true : false;

if($res) {
    echo "good";        
} else {
    echo "fail";
}

Thanks!


If the results you are returning from the ternary operator are only "true" and "false", then you don't even need the operator. You can just have:

$res = (($rule1 === true) && ($rule2 === false) && ($rule3 === true))

But, to answer your question, yes multiple conditions work perfectly well.


It's totally legal, it works and is "as reliable as if", but it looks ugly.

If you put each ternary statement inside parenthesis, nesting would be fine too:

$res = ( $rule1 ? true : ( $rule2 ? true : false ) )

The only thing that is advised against in the manual is nesting without parenthesis like this:

$res = ( $rule1 ? true : $rule2 ? true : false )


Is there a reason you want to have your conditions saved into a variable? this is the simplified version of above.

if($rule1 && !$rule2 && $rule3)
{
    echo "good";
}
else
{
    echo "bad";
}


You do not need the ternary if you are going to return true or false. Quoting the manual:

The expression (expr1) ? (expr2) : (expr3) evaluates to expr2 if expr1 evaluates to TRUE, and expr3 if expr1 evaluates to FALSE.

This means

$res = (($rule1 == true) && ($rule2 == false) && ($rule3 == true));

will assign true or false already. Also, if dont care about $rule being booleans, you dont need the comparison with ==. You also dont need the braces, e.g.

$res = $rule1 && !$rule2 && $rule3;

is the same as your initial ternary.

A good practise when you have multiple expressions like that is to hide the actual comparison behind a meaningful method or function name, e.g.

function conditionsMet($rule1, $rule2, $rule3) {
    return $rule1 && !$rule2 && $rule3;
}

and then you can do

if (conditionsMet($rule1, $rule2, $rule3)) {
    // do something
}

Of course, conditionsMet isnt that meaningful. A better example would be something like isSummerTime or isEligibleForDiscount and so on. Just express what the rules express in the method name.

You might also be interested in Simplifying Conditional Expressions from the book Refactoring - Improving the design of existing code.


You can also do

 $res = ($rule1 && !$rule2 && $rule3);


It's legal and doesn't have to be "ugly". I use the "hook" operator often, in table form it's quite clean, e.g.:

bool haveANeed() 
{ 
    //     Condition       result
    //     ----------      ------
    return needToEat()   ? true
         : needToSleep() ? true
         : needToStudy() ? true
         : needToShop()  ? true
         : needToThink() ? true
         :                 false; // no needs!
}

This function would, IMHO, be less clear and certainly longer if written with if-else logic.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜