From: "Robert E. Glaser" on
My ISP upgraded his server from Ubuntu 9.04 to Ubuntu 9.10, which
probably included a newer PHP version. I don't know what PHP version
was on previously. Code I've had running for years broke, and I tracked
it down to this equivalent:

<?php

echo 'Current PHP version: ', phpversion(), "<br><br>";

$Condition0 = true and false;
If ($Condition0)
echo "Condition0<br>";
else echo "Not Condition0<br>";

$Condition1 = false and true;
If ($Condition1)
echo "Condition1<br>";
else echo "Not Condition1<br>";

$Condition2 = (true and false);
If ($Condition2)
echo "Condition2<br>";
else echo "Not Condition2<br>";

$Condition3 = true && false;
If ($Condition3)
echo "Condition3<br>";
else echo "Not Condition3<br>";

$Condition4 = (true && false);
If ($Condition4)
echo "Condition4<br>";
else echo "Not Condition4<br>";
?>

which returns:

Current PHP version: 5.2.10-2ubuntu6.4

Condition0
Not Condition1
Not Condition2
Not Condition3
Not Condition4

===============================

I added parentheses around the offending line of code and it seems okay
now. But I am stymied as to why they're required at all. They never
were before, and as far as I see there is no PHP requirement to include
the parentheses. Have I done something silly? Mostly I'm worried if
there are any other changes I need to make. I searched my code and
hopefully found all similar instances, but who really knows about those
kinds of things?

Any comments?

---Robert

From: Paul M Foster on
On Tue, Sep 07, 2010 at 10:41:46PM -0400, Robert E. Glaser wrote:

> My ISP upgraded his server from Ubuntu 9.04 to Ubuntu 9.10, which
> probably included a newer PHP version. I don't know what PHP version
> was on previously. Code I've had running for years broke, and I tracked
> it down to this equivalent:
>
> <?php
>
> echo 'Current PHP version: ', phpversion(), "<br><br>";
>
> $Condition0 = true and false;
> If ($Condition0)
> echo "Condition0<br>";
> else echo "Not Condition0<br>";
>
> $Condition1 = false and true;
> If ($Condition1)
> echo "Condition1<br>";
> else echo "Not Condition1<br>";
>
> $Condition2 = (true and false);
> If ($Condition2)
> echo "Condition2<br>";
> else echo "Not Condition2<br>";
>
> $Condition3 = true && false;
> If ($Condition3)
> echo "Condition3<br>";
> else echo "Not Condition3<br>";
>
> $Condition4 = (true && false);
> If ($Condition4)
> echo "Condition4<br>";
> else echo "Not Condition4<br>";
> ?>
>
> which returns:
>
> Current PHP version: 5.2.10-2ubuntu6.4
>
> Condition0
> Not Condition1
> Not Condition2
> Not Condition3
> Not Condition4
>
> ===============================
>
> I added parentheses around the offending line of code and it seems okay
> now. But I am stymied as to why they're required at all. They never
> were before, and as far as I see there is no PHP requirement to include
> the parentheses. Have I done something silly? Mostly I'm worried if
> there are any other changes I need to make. I searched my code and
> hopefully found all similar instances, but who really knows about those
> kinds of things?
>
> Any comments?

I can't tell what (if anything) changed or why. But the problem appears
to rest with the fact that "&&" is higher precedence than "=", and "and"
is lower precedence. Here are two references:

http://us.php.net/manual/en/language.operators.logical.php

http://us.php.net/manual/en/language.operators.precedence.php

It's tricky, I'll admit. Since I normally mean for things I'm logically
"anding" to be "anded" before any other operation, it's forced me to
change almost all my "ands" to "&&". Just so I don't make a mistake.

Also note the "associativity" in the second reference.

Paul

--
Paul M. Foster
From: David Harkness on
The reason for "and" to have such a low precedence is so you can use it to
perform conditional processing. You can probably achieve every effect using
"&&", but you'd need more parentheses. More typically you would use "or" in
this fashion:

defined('DS') or define('DS', DIRECTORY_SEPARATOR);

This checks if DS is defined and defines it if not.

APP_ENV != 'prod' or die('This feature must not be used in production');

If we're in production, stop execution with an error. Using || here would
try to logically or the string 'prod' with the return value of die(). Of
course, die() doesn't return, so the script would exit no matter what
APP_ENV was set to.

David
From: David Harkness on
On Wed, Sep 8, 2010 at 9:55 AM, Peter Lind <peter.e.lind(a)gmail.com> wrote:

> || and && would work exactly like 'or' and 'and' in the above. ==, !=,
> === and !=== have higher precedence than || or &&
>

Ah, you're correct. The only operators between &&/|| and and/or and the
ternary ?: and assignment operators. Thus the need for the parentheses in

$Condition2 = (true and false);

to make $Condition2 false. The parentheses in

$Condition4 = (true && false);

are redundant since && has higher precedence than = (assignment).

Robert, how do the results differ from your expectations?

David
From: "Robert E. Glaser" on
> Robert, how do the results differ from your expectations?
>
> David

It's hard to wrap my mind around the concept that the assignment
operator itself has an operator precedence. Which means that one could
write expressions without any assignment at all, and be syntactically
correct.

I cannot believe that the later release of php brought this out, it must
have always been there. In my case it was evidenced by the subsequent
open a nonexistent file instruction which provided a warning message;
that warning must somehow have been inhibited in the earlier php
installation, so I never knew about my incorrect "and" usage. It's a
shared database program which has been operational for five years with
no detected bugs. I actually feel better believing that the newer php
version probably had no effect whatsoever on my code, just a warning
message -- so the code itself is most likely just as solid (or not) as
it ever was.

I do tend to overuse parentheses in my code just for clarity, I slipped
and left them out for the so simple statement A = B and C. Live and learn!

Thanks,
---Robert