php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #53117 Assignment by reference within assignment operator
Submitted: 2010-10-20 18:53 UTC Modified: 2010-10-22 10:17 UTC
From: dukeofgaming at gmail dot com Assigned: aharvey
Status: Closed Package: Documentation problem
PHP Version: 5.2.14 OS: Any (Windows 7)
Private report: No CVE-ID:
 [2010-10-20 18:53 UTC] dukeofgaming at gmail dot com
Description:
------------
Hi,

PHP throws a fatal error when code like this is processed:

$my_var = (true)?(&$some_obj):(&$some_other_obj->some_arr_pop[]);

Which is not a problem if put like this of course:

$my_var;
if(true){
  $my_var = &$some_obj;
}else{
  $my_var = &$some_other_obj->some_arr_pop[];
}

Affects both PHP 5.2.x and 5.3.x


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-10-20 22:15 UTC] cataphract@php.net
-Status: Open +Status: Bogus
 [2010-10-20 22:15 UTC] cataphract@php.net
This is not a bug. The ternary operator defines an expression. Even if it allowed yielding a reference (it doesn't), you are not assigning by reference in

$my_var = ...

The assign by reference operator is "=&", not "=".
 [2010-10-20 23:24 UTC] dukeofgaming at gmail dot com
I am not under the impresion that there is an asign-by-reference operator as such, 
since one is free to separate "=" from "&", where "&" indicates return by 
reference. However the expression part makes this clear.

Regards,

David Vega
 [2010-10-21 00:39 UTC] cataphract@php.net
> I am not under the impresion that there is an asign-by-reference
> operator as such, since one is free to separate "=" from "&", where
> "&" indicates return by reference.

Not really. See the parser definitions here:

http://lxr.php.net/xref/PHP_5_3/Zend/zend_language_parser.y#expr_without_variable

The only (non-deprecated) form of an assignment by reference is:

variable '=' '&' variable { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$4, BP_VAR_W, 1 TSRMLS_CC); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }

The fact you can separate "=" and "&" is maybe unfortunate, because it causes the sort of confusion you have. Although "&" is used in several similar contexts (pass by reference, return by reference, assign by reference, include reference in array expression) and they all share a common implementation pattern (what in PHP is sadly called "references", which is actually just a "no copy flag"), they are still conceptually different processes, with some dissimilarities.

In particular, in PHP there are different opcodes for assignment (operator =) and assignment by reference (operator =&). To assign by reference, you don't need just a "reference" (a variable that has the is_ref no copy flag) or something from which we can extract a reference on the right hand side, we need to actually use the "assign by reference" operator.

Consider:

$a =& $b;
$c = $a; //not an assignment by reference, but $a is a "reference".
function &h() { return $GLOBALS['b']; }
$c = h(); //not an assignment by reference, but h() returns by reference
 [2010-10-21 00:57 UTC] dukeofgaming at gmail dot com
Hi again,

Thanks for the detailed follow-up. I did not have the slightest idea that this 
form of using '&' was deprecated. If '=&' is formally an operator, shouldn't it be 
in the "Assignment Operators" section of the documentation?.

Regards
 [2010-10-21 02:06 UTC] cataphract@php.net
It's not deprecated. What's deprecated is "=& new something()".

The documentation page for "Assignment operators" talks briefly about "=&", but it could use some improvements (it even includes the somewhat inaccurate statement that in PHP 5 objects are assigned by reference).
 [2010-10-21 02:10 UTC] cataphract@php.net
-Type: Bug +Type: Documentation Problem -Package: *Compile Issues +Package: Documentation problem
 [2010-10-21 02:10 UTC] cataphract@php.net
-Status: Bogus +Status: Open
 [2010-10-22 09:34 UTC] aharvey@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: aharvey
 [2010-10-22 10:15 UTC] aharvey@php.net
Automatic comment from SVN on behalf of aharvey
Revision: http://svn.php.net/viewvc/?view=revision&revision=304605
Log: Fix doc bug #53117 (Assignment by reference within assignment operator) by
breaking out the previously brief discussion of using the assignment operator
to assign by reference into its own subsection, including a reference to
by-reference assignments of new expressions being deprecated. Also updated the
References Explained section to reflect 5.3+ generating E_DEPRECATED errors in
that case, rather than E_STRICT.
 [2010-10-22 10:17 UTC] aharvey@php.net
-Status: Assigned +Status: Closed
 [2010-10-22 10:17 UTC] aharvey@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.

That should be a distinct improvement. I've left the bit in about
objects being assigned by reference -- I know it's not strictly true,
but it's an accurate enough representation of the actual behaviour,
and users who are that interested in how objects are passed are
likely to end up finding Sara's blog on the subject. (We could add a
See Also section linking to that blog, but I think it might only
confuse matters further.)
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Wed Apr 16 16:02:23 2014 UTC