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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: johanp at aditus dot nu
New email:
PHP Version: OS:

 

 [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

Pull Requests

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: Sun Dec 22 01:01:30 2024 UTC