문제

In PHP I have this if statement ( $first and $second will evaluate to true or false):

if ($first && $second) {
    // evereything is OK
} else {
    throw new Exception()...
}

My real code is much more complicated, I am trying to make simple example here.

I want to turn this if/else into one if with negation like this:

if (!($first && $second)){
    throw new Exception()...
}

// everything is OK

As you can see in this example, I've put ! negation sign in front of parentheses. Is this correct ? Do I need to negate every condition itself like this:

if (!$first && !$second)

Or I should use || operator:

if (!$first || !$second) // I am using OR here

I am not sure how these conditions are going to evaluate at the end, and I am confused by my dummy testing results. I really hope that someone can explain to me how all these checks are going to evaluate at the end.

Thanks to everyone who answered my question. Due to my low rep, I can not up-vote or pick some answer as the right one. You are all good for me :)

도움이 되었습니까?

해결책

Build a truth table:

p  q    p && q    p || q    !(p && q)    !p || !q    !(p || q)   !p && !q
==========================================================================
0  0    0         0         1            1           1           1
0  1    0         1         1            1           0           0
1  0    0         1         1            1           0           0
1  1    1         1         0            0           0           0

Thus, you see that !(p && q) is equivalent to !p || !q, but not equivalent to !p && !q. You see that !(p && q) and !p || !q are the opposite of p && q.

Note that !(p && q) and !p || !q are equivalent and can be proved by using the De Morgan's laws.

다른 팁

Yes, it should be fine. By negating the condition in the if, you're only picking up the cases that would have failed before.

Also, !($first && $second) is equivalent to (!$first || !$second), not (!$first && !$second). (Because DeMorgan's, as other answerers have mentioned).

If your results are confusing you, you could use a truth table to evaluate the expressions and find the one that fits the behavior you're looking for.

Once you have the right expression, you want to make sure you place your parentheses correctly, like ratchet freak mentioned.

These can help get you started: Truth Tables. Truth Table Generator. For the latter, you'll have to convert the operators to the ones they use.

if (!$user == 'john' || !$status == 'active')

This does not quite do what you think it does.

If you add the brackets as the parser will add them you get:

if ( (!$user) == 'john' || (!$status) == 'active')

While you want:

if (!($user == 'john') || !($status == 'active') )

The fix to this is to add the explicit brackets or to use the not equals operator != or !== depending on if you want the identity check as well.

Besides that this is where de Morgan's laws come in.

These state that !(a||b) == (!a && !b) and that !(a&&b) == (!a || !b)

As you can see in this example, I've put ! negation sign in front of parentheses. Is this correct ?

Yes, that is fine.​​​​​​​​​​​​​​​​​

Do I need to negate every condition itself like this:

if (!$first && !$second)

No, that would actually be wrong.

Or I should use || operator:

if (!$first || !$second)

Yes, that would be correct.

It would also be my personal preference of all the options you propose.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 softwareengineering.stackexchange
scroll top