Here's what's exactly happening in each of your examples:
echo 0 or 1;
is evaluated as
echo (0 or 1);
or takes precedence over the echo language construct.
$foo = (0 or 1);
is evaluated as is. Anything in parentheses takes precedence depending on the level of nesting of parentheses. In this case, 0 or 1 is evaluated first, which results in 1, which is then assigned to $foo.
$foo = 0 or 1;
is evaluated as
($foo = 0) or 1;
Here, variable assignment (with the = operator) takes precedence over or. The assignment statement has a value of 0, which evaluates to false, so PHP looks at the next condition, which is 1. The 1 is completely irrelevant to the assignment of $foo, which is now 0.