The PHP Language Specification says:
A variable is an expression that can in principle be used as an lvalue
and
The value of a function call is a modifiable lvalue only if the function returns a modifiable value byRef.
and the grammar from zend_language_parser.y
expr:
variable T_CONCAT_EQUAL expr
callable_variable:
simple_variable
{ $$ = zend_ast_create(ZEND_AST_VAR, $1); }
| dereferencable '[' optional_expr ']'
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| constant '[' optional_expr ']'
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| dereferencable '{' expr '}'
{ $$ = zend_ast_create_ex(ZEND_AST_DIM, ZEND_DIM_ALTERNATIVE_SYNTAX, $1, $3); }
| dereferencable T_OBJECT_OPERATOR property_name argument_list
{ $$ = zend_ast_create(ZEND_AST_METHOD_CALL, $1, $3, $4); }
| function_call { $$ = $1; }
;
variable:
callable_variable
{ $$ = $1; }
| static_member
{ $$ = $1; }
| dereferencable T_OBJECT_OPERATOR property_name
{ $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); }
;
So why can't I do this in PHP 7.3?
<?php
$a = 'HELLO';
function &foo() {
global $a;
return $a;
}
foo() .= ' WORLD';
echo $a;
PHP Fatal error: Can't use function return value in write context in ...
To follow on from this question, with reference to the grammar above:
When is it ok to have a function call on the left hand side of a simple/compound assignment expression?