php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #34358 Fatal error: Cannot re-assign $this
Submitted: 2005-09-03 13:36 UTC Modified: 2010-09-03 23:34 UTC
Votes:7
Avg. Score:4.7 ± 0.7
Reproduced:7 of 7 (100.0%)
Same Version:7 (100.0%)
Same OS:7 (100.0%)
From: pacha dot shevaev at gmail dot com Assigned: dmitry
Status: Closed Package: Scripting Engine problem
PHP Version: 5.* OS: *
Private report: No CVE-ID:
 [2005-09-03 13:36 UTC] pacha dot shevaev at gmail dot com
Description:
------------
PHP 5.1RC1 throws fatal error when some variable gets assigned with $this by reference. However there's a workaround for this fatal error which is very simple: using a helper function which simply returns the passed argument by reference. I'm a bit lost here - what is the expected behavior?

Yes, it may seem a bit weird to assign objects by reference in PHP5 but if you keep your code base PHP4 compatible you know what i mean. 

Reproduce code:
---------------
<?php

function & getRef(&$ref) {
  return $ref;
}

class Foo {
  function Foo() {
    //$ref =& getRef($this); //works just fine
    $ref =& $this; //throws "cannot re-assign $this" fatal
    $ref->test();
  }

  function test() {
    echo 'test';
  }
}

$foo = new Foo();

?>

Expected result:
----------------
test

Actual result:
--------------
Fatal error: Cannot re-assign $this

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-09-03 13:41 UTC] helly@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

Objects are already references in PHP 5, thuse there is no sense in ...&$this in any way.
 [2005-09-15 13:37 UTC] pacha dot shevaev at gmail dot com
I still find it a bug. I need a reference to $this for BC with PHP4 in the following piece of code:

    function &getRootDataSource() {
        $root =& $this;
        while ($root->parent != NULL) {
            $root =& $root->parent;
        }
        return $root;
    }
 [2005-09-15 14:27 UTC] sniper@php.net
NOTE: This is about PHP 5. It might have worked in PHP 4 but it does not and will not work in PHP 5.
 [2005-09-15 15:23 UTC] pacha dot shevaev at gmail dot com
I'm not an expert in PHP internals but there's a guy(stereofrog) on the SitePoint forum who has a different point of view(http://www.sitepoint.com/forums/showpost.php?p=2146304&postcount=9):

[quote]
it's 'simply ridiculous. They have a code in zend_compile.c that handles "$this=$x" and copy-pasted that code in the function that comples assignment by reference. This should prevent "$this=&$x" (which is wrong), but for some reason it "prevents" "$x=&$this" as well (which is absolutely correct). It's pure c-level bug and has nothing to do with "new object model" and other blah-blah.
[/quote]
 [2005-09-15 15:28 UTC] derick@php.net
It's still bogus, you can call it a BC break if you want, but we're not going to change this back.
 [2005-09-15 15:32 UTC] pacha dot shevaev at gmail dot com
And why does the following code work then???

<?php

class Foo {
  function Foo() {
    $this->ref =& $this;
    $this->ref->test();
  }

  function test() {
    echo 'test';
  }
}

$foo = new Foo();

?>
 [2005-10-03 09:40 UTC] rasmus@php.net
It has everything to do with the new object model.  Take this code:

  $x = &$this;
  $x = 'foo';

For performance reasons we need to catch such references when they happen in order to prevent the object being overwritten inside itself.  It would be a bit less confusing if the error happened on the actual assignment, but in this new object model there $x = &$this; is just as wrong as $this = &$x since the only purpose one could have for making a reference to $this itself is if you wanted to change it directly.  In all valid cases this should be $x = $this.

I suppose an option would be to ignore the reference in this case and continue on.  That seems to be happening with that last indirect case you posted, but it would cost us a lookup.
 [2005-10-03 10:22 UTC] dmitry@php.net
Fixed in CVS HEAD and PHP_5_1.
 [2005-10-03 12:14 UTC] rasmus@php.net
So for the curious who are wondering what "fixed" means.  The & is simply ignored in this case now. 
 [2005-10-03 12:42 UTC] derick@php.net
I'm reopening this so that we can discuss it. I don't think we should be silently ignoring references as that's something vague. See mail to internals@ in a bit.
 [2005-10-04 08:01 UTC] pacha dot shevaev at gmail dot com
Guys your notes about possible misuse($ref =& $this;$ref = 'foo') are totally valid but is soooooo much difficult to spot this situation _when_it_actually_happens_? 

I'm by no means going to use this ref improperly but simply want BC with PHP4...
 [2005-10-21 10:07 UTC] dmitry@php.net
This bug is fixed.

Disallowing $a = &$this; and foo(&$this) is a feature request (not a bug). Also I don't see any sense no breake BC and valid code only because this assignment is dangerous.
 [2010-09-03 23:12 UTC] az_startreker at yahoo dot com
$this = mysql_last_id();

I got the same error as previously stated. Worked fine in PHP 4. I use the variable $this in the very next line of code for a database entry, but it keeps kicking back fatal errors at this line.
 [2010-09-03 23:34 UTC] pajoye@php.net
It is not allowed anymore for obvious reasons. Please read the migration guide and the PHP manual for more details.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 00:01:21 2014 UTC