Ah, yes, booleans - bit values that are either set (TRUE) or not set (FALSE). Now that we have 64 bit compilers using an int variable for booleans, there is *one* value which is FALSE (zero) and 2**64-1 values that are TRUE (everything else). It appears there's a lot more truth in this universe, but false can trump anything that's true...
PHP's handling of strings as booleans is *almost* correct - an empty string is FALSE, and a non-empty string is TRUE - with one exception: A string containing a single zero is considered FALSE. Why? If *any* non-empty strings are going to be considered FALSE, why *only* a single zero? Why not "FALSE" (preferably case insensitive), or "0.0" (with how many decimal places), or "NO" (again, case insensitive), or ... ?
The *correct* design would have been that *any* non-empty string is TRUE - period, end of story. Instead, there's another GOTCHA for the less-than-completely-experienced programmer to watch out for, and fixing the language's design error at this late date would undoubtedly break so many things that the correction is completely out of the question.
Speaking of GOTCHAs, consider this code sequence:
<?php
$x=TRUE;
$y=FALSE;
$z=$y OR $x;
?>
Is $z TRUE or FALSE?
In this case, $z will be FALSE because the above code is equivalent to <?php ($z=$y) OR $x ?> rather than <?php $z=($y OR $x) ?> as might be expected - because the OR operator has lower precedence than assignment operators.
On the other hand, after this code sequence:
<?php
$x=TRUE;
$y=FALSE;
$z=$y || $x;
?>
$z will be TRUE, as expected, because the || operator has higher precedence than assignment: The code is equivalent to $z=($y OR $x).
This is why you should NEVER use the OR operator without explicit parentheses around the expression where it is being used.