PHP Sadness

(<5.6) Occasionally significant parentheses

There are cases where simply wrapping code in parentheses changes the result. For example, consider a function r() which returns a reference to its argument:

// r() simply returns a reference to a given variable.
function &r(&$v){return $v;}

// Here, we have a scalar $a on which settype() fails to operate if
// parentheses are involved.
print "Scalar demonstration:\n";
$a = 1;

// First with parentheses, then without.
//       v       v
settype( ( r($a) ) , "boolean"); var_dump($a);
settype(   r($a)   , "boolean"); var_dump($a);
//       ^       ^

// Here is a similar situation where array_pop() fails to operate upon a
// reference to an array if parentheses are involved.
print "\nArray demonstration:\n";
$b = array("c");

// First with parentheses, then without.
//         v       v
array_pop( ( r($b) ) ); print_r($b);
array_pop(   r($b)   ); print_r($b);
//         ^       ^

Note how, in both demonstrations, the first invocation has no effect:

Scalar demonstration:

Array demonstration:
    [0] => c

Apparently, references are so fragile (read: such a special case in the parser) that even parentheses force them back into plain values.

(E_STRICT will emit a warning here; that still does not make this behavior okay. "Strict Standards: Only variables should be passed by reference ...")

Significance: Implications for Internals

The mere presence of this issue tends to imply some fatal flaw or unnecessary complexity at the most basic levels of the language. For example, an overly complex parser might be trying to compensate for missing functionality in the interpreter by incorrectly (and misleadingly) validating code at the syntax level, or messages without details could indicate that the internal design prohibits access to values where they should be reachable in a sane implementation.