php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #8935 A reference to 'this' can not be used in the constructor method for a class.
Submitted: 2001-01-26 09:37 UTC Modified: 2001-03-13 05:00 UTC
From: johanp at aditus dot nu Assigned:
Status: Closed Package: Class/Object related
PHP Version: 4.0.4 OS: Linux/WinNT
Private report: No CVE-ID: None
 [2001-01-26 09:37 UTC] johanp at aditus dot nu
The following script demonstrates the problem.

<?php
/*
thistest.php
jp, 2001-01-25
Demonstration of bug in passing '$this' as a reference in the constructor.
The problem is that it will not be a reference to the newly created object that is passed but rather a new copy. This is demonstrated below.

The Container class is just a driver class

The bug is demostrated in the A1 class. The A class uses an Init() method to pass the '$this' reference which is a workaround for this particular bug.

Analysis of problem:
It seems that the '$this' pointer is not safe to use in the constructor since it probably doesn't get properly initialized for the object until after the constructor has been run.

*/



class ContainerA {
    var $a;
    function ContainerA() {
        $this->a=new A();
        $this->a->Init();
        echo "A val before calling change: ".$this->a->val."<br>";
        $this->a->bobj->ChangeA();
        echo "A val after calling change (should be 3): ".$this->a->val."<br>";
    }
}

class A {
    var $val=1;
    var $bobj=null;

    function A() {
       $this->bobj = new B();
    }
    function Init() {
       // Workaround it is safe to use a refernce to this outside the constuctor
       $this->bobj->Init(&$this);
    }
    function SetVal($v) {
        $this->val=$v;
    }
};

class B {
      var $aobj=null;
      function B() {
      }
      function Init(&$obj) {
         $this->aobj=&$obj;
      }
      function ChangeA() {
         $this->aobj->SetVal(3);
      }
};

class ContainerA1 {
    var $a;
    function ContainerA1() {
        $this->a=new A1();
        echo "A val before calling change: ".$this->a->val."<br>";
        $this->a->bobj->ChangeA();
        echo "A val after calling change (should be 3): ".$this->a->val."<br>";
    }
}

// BUG
class A1 {
    var $val=1;
    var $bobj=null;

    function A1() {
        $this->bobj = new B();

        // BUG. A reference of 'this' is NOT passed here as it seems but a copy!
        // Hence the bobj will contain another copy of A1 and not the one we
        // are just creating.
        $this->bobj->Init(&$this);
    }
    function SetVal($v) {
        $this->val=$v;
    }
};

echo "Demonstration of 'this' bug.<p>";
echo "Using class A (workaround)<br>";
$c1=new ContainerA();

echo "<p>Using class A1 (BUG)<br>";
$c1=new ContainerA1();

?>

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-02-24 14:14 UTC] jmoore@php.net
Please see the 4.0.4 release change log a lot of things along this line were fixed.

James
 [2001-03-09 13:50 UTC] andre@php.net
this has been fixed for months,
please use =& new instead of = new in this special case
 [2001-03-09 17:09 UTC] sniper@php.net
It's fixed -> closed.

--Jani

 [2001-03-09 17:26 UTC] andre@php.net
not really this is only a duplicate report for an already
fixed bug...
 [2001-03-09 18:24 UTC] andre@php.net
I have added some notes to the documenation, as far as the
the site has been updated its documenatation check it out
"language.oop.newref.html" (http://snaps.php.net/manuals/)
it may take a day or two ...
 [2001-03-13 05:00 UTC] johanp at aditus dot nu
I haven't tried the $a = & new syntax 

However, is that really a working solution? This would
require all clients of that class to actually have to know that the constructor would like to use a &$this reference and hence the clients must know about the specific implementation.

Is that such a good idea? Wouldn't it be better to allow
the use of &$this in a constructor as default without having to create the class with this special version of new().

or did I mmiss something here?

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 11:01:29 2024 UTC