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归因
scroll top