php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #28491 $this may be modified indirectly inside a method
Submitted: 2004-05-22 17:19 UTC Modified: 2006-01-02 09:07 UTC
Votes:4
Avg. Score:2.8 ± 1.5
Reproduced:2 of 4 (50.0%)
Same Version:2 (100.0%)
Same OS:0 (0.0%)
From: ladislav dot prosek at matfyz dot cz Assigned:
Status: Wont fix Package: Class/Object related
PHP Version: 5.0.0RC2 OS: Windows XP Pro
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [2004-05-22 17:19 UTC] ladislav dot prosek at matfyz dot cz
Description:
------------
Trying to assign to $this inside a method results in:
"Fatal error: Cannot re-assign $this".

However, using a reference it is possible to modify $this.

Reproduce code:
---------------
class A
{
  function f()
  {
    $p =& $this;
    $p = "whatever";

    var_dump($this);

    // Note: accessing fields and invoking methods
    // via $this still works fine.
  }
};

$x = new A();
$x->f();


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

Actual result:
--------------
string(8) "whatever"

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-05-23 21:01 UTC] pollita@php.net
Thank you for reprting this issue.  First I'd like to clarify what's going on:

$this is a very special variable.  In reality it's a combination of run-time variable and compile-time token.

Direct assignment to $this is resolved at compile time (as opposed to execution time for all other variables) and is disallowed using the error message you mentioned.

Creating a reference to $this is resolved at execution time as is any normal variable assignment (including assignment to a reference to $this).  While it is possible to perform a check to be sure that the variable being assigned to is not a reference to $this, that check would have to be performed for every single assignment.  This'll slow things down, let's put that in the 'minus' column.

Now, let's look at what indirectly reassigning $this does to the engine:

When an object property or method is accessed using $this->prop; or $this->meth();  The object indirection is resolved at compile time (this ultimately saves time during execution since the object's prop table  and virtual method table don't need to be repeatedly looked up at execution time).  This is why var_dump($this); can show the modified value (a string) while $this->prop; and $this->meth(); still work as though nothing's changed.  When the method in which $this was indirectly redefined ends however, $this is simply discarded to be "recreated" from the calling scope the next time a method is called.

Given the choice between: (A) doing nothing but leaving room for confusion, (B) taking away the ability to create references, or (C) checking assignments for references to $this(read: slow);  The current decision is to go with (A).

This may be revisited prior to the release of PHP 5.1, at which point there may be a fourth option which avoids the pitfalls of each of the three previously ennumerated routes, for the time being I'm flagging this report as 'Suspended'.
 [2005-06-20 09:57 UTC] skissane at iips dot mq dot edu dot au
With regards to Polita's comments...

The compiler already checks for, and disallows, assignments in which $this is on the LHS at compile-time, e.g. $this = 0; $this =& $x;

Why not just have the compiler do a similar compile-time check on the RHS for references, i.e. <variable> =& $this; is detected at compiletime and causes a compiletime error? That should have minimal performance issues.
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC