$all_confirmed = (count($changed_coefs_ids) == 0) AND (!$payout_too_big);

$all_confirmed = (count($changed_coefs_ids) == 0) && (!$payout_too_big);

How do you think, should those code lines get the same result?

I got different result (comment out one line, then uncooment and comment out another)

Wasted time till I noticed that, since that doens't make sense for me, this was probably the last thing I tried to check.

According to the PHP manual the only difference between && and AND is that && is higher in precedence and gets evaluated before AND, otherwise hey do the same thing (logical comparison). This should not affect your example since you use parentheses and ! has higher precedence anyway. Can you post the exact values that get you different results since this is interesting question for me, too.

OK after some thinking, the reason is that = operator has higher precedence than AND and lower precedence than && (see http://www.php.net/manual/en/language.operators.precedence.php). So it pays to be careful with this. To be safe put the whole expresion on the right into parentheses:

$all_confirmed = ((count($changed_coefs_ids) == 0) AND (!$payout_too_big));
$all_confirmed = ((count($changed_coefs_ids) == 0) && (!$payout_too_big));
Member Avatar for jmichae3

personally, I think you have found a bug in PHP. report it.

yeah, with aditional ( ) it now works ok. I don't pay attention too much to that precedence, but I think this is stupidly made. What is the point to have such not self explanatory syntax, by which you can make mistakes and not even notice. For me they looked the same, so I expected the same result.

I mean if withouth those ( ) which you added and just looking at the code - how could you tell that it would return different value? Unless you are PHP guru who knows every small peace of language specifics.

Member Avatar for jmichae3

and whan you report the bug in PHP, you might want to echo the values of the lhs and rhs (left hand side and right hand side).

maybe its not the bug, I am not sure, because I dindn't examine those precedence stuff. Maybe this is a feature :D

I don't think this is a bug. I think it was made this way with some purpose (maybe sometimes you need assignment before a comparison - I haven't had such a case yet).

But I agree that users are not warned enough about the difference between AND and && and other precedence issues. I found one warning in comments of users.

One such practical use of the above precedence can be found in the examples section of the manual (see the last example):

$page = (int) @$_GET['page'] or $page = 1;

It would probably not work with || (not tested).

if (!empty($_GET['page']) {
    $page = $_GET['page'];
} else {
    $page = 1
}

I would prefer this instead :) why the hell need those complications :)

maybe not even name variable $page, but name $a then if we become better coders by making code to read more dificullt?

I am quite used to code this way and it looks pretty clean to me. This code snippet actually appears on so many pages that became quite familiar. Or the other even more popular one:

$result = mysql_query($query) or die();

A lot of people use this.

I would use the short hand if statement: $page = ( isset( $_GET['page'] ) && is_numeric( $_GET['page'] ) ? (int) $_GET['page'] : 1 ); to keep it short and not feel dirty.

Member Avatar for jmichae3

check your logic if you are getting weird results. I check out the operators using the logic of your equation. they are just fine, no bug there. operator precedence has nothing to do with this.

Thu 05/31/2012 14:46:44.45|C:\Documents and Settings\Jim Michaels|>php
<?php
echo (true and true)?"true\n":"false\n"; //should be true
echo (false and true)?"true\n":"false\n"; //should be false
echo (true and false)?"true\n":"false\n"; //should be false
echo (false and false)?"true\n":"false\n"; //should be false
echo "\n";
echo (true && true)?"true\n":"false\n"; //should be true
echo (false && true)?"true\n":"false\n"; //should be false
echo (true && false)?"true\n":"false\n"; //should be false
echo (false && false)?"true\n":"false\n"; //should be false
?>
^Z
true
false
false
false

true
false
false
false

<?php
echo ((0==0) and (!false))?"true\n":"false\n"; //should be true
echo ((1==0) and (!false))?"true\n":"false\n"; //should be false
echo ((0==0) and (!true))?"true\n":"false\n"; //should be false
echo ((1==0) and (!true))?"true\n":"false\n"; //should be false
echo "\n";
echo ((0==0) && (!false))?"true\n":"false\n"; //should be true
echo ((1==0) && (!false))?"true\n":"false\n"; //should be false
echo ((0==0) && (!true))?"true\n":"false\n"; //should be false
echo ((1==0) && (!true))?"true\n":"false\n"; //should be false
?>
^Z
true
false
false
false

true
false
false
false

@jmichae3 it's not a bug, but there is a different behaviour, just try this:

$a = true;
$b = false;

$c[] = $a and $b;
$c[] = $a && $b;

var_dump($c);

as output you will get:

array(2) {
  [0]=>
  bool(true)
  [1]=>
  bool(false)
}

when you should get always false, this happens because the expression with and is working like this:

($c[] = $a) and $b;

instead of:

$c[] = ($a and $b);

and this is why broj1 wrote about the higher precedence of &&. Bye!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.