php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #7482 this is not reference in class constructor: Bug 6896 extension/correction
Submitted: 2000-10-26 11:14 UTC Modified: 2000-12-06 16:53 UTC
From: danjrod at terra dot es Assigned:
Status: Closed Package: Class/Object related
PHP Version: 4.0.3pl1 OS: RedHat Linux-6.2
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: danjrod at terra dot es
New email:
PHP Version: OS:

 

 [2000-10-26 11:14 UTC] danjrod at terra dot es
Bug 6896 (suspended) states:
  'a class cannot have a reference to its instance'

The real problem lies within the constructor. If you
try using a this as reference in the constructor you
will get a copy.

If you use this as a reference in any other member function
it will work. Snippet below!.

My guess: Temp object is created during object construction
and this is 'this'. Then copy is made to be returned and 'temp' is deleted unless you have made a reference to temp.


No specific setup. I simply want to pass this by reference to other objects. It won?t work from the class constructor. I have checked mail archives

./configure --with-mysql

php.ini is default.

script reproducing the problem

class t1_t { 
var $a; 
function t1_t( &$p, $a) { 
$this->a = $a; 
$p->add( $obj); 
} 
function set( $a) { 
$this->a = $a; 
} 
function get() { 
return $this->a; 
} 
} 

class testing_t { 
var $obj; 

function testing_t() { 
$this->obj = array(); 
} 
function add( &$obj) { 
$this->obj[] = &$obj; 
} 

function html() { 
echo "starting<br>\n"; 
reset( $this->obj); 
while( list( $i, $obj) = each( $this->obj)) { 
echo $obj->get() . "<br>\n"; 
} 
echo "ending<br>\n"; 
} 
} 

$l = new testing_t(); 

$a1 = new t1_t( $l, "5"); 
// uncommenting this solves the problem
// $l->add( $a1);
$a1->set( "27"); 

$a2 = new t1_t( $l, "7"); 

$l->html(); 

// output should read 5 and 27 but it says 5 and 7.

?> 



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2000-10-27 16:01 UTC] danjrod at terra dot es
I think I know what the problem is:

      - Call constructor:

      - An object is created. &$this is a reference
        to the instance.

      - Object is returned. A copy of the object is
        returned instead of a reference, thus the original
        &$this points to the original object and not
        to the returned object.

      - Since "&new object_t()" and "new &object_t()" are
        not available, you can never get a reference to
        the original object but a copy.

I think the solution would be to have constructor always return a reference.

I have developed a 3 line patch that has solved the problem for me. It may cause trouble as I am not a bison/yacc expert (not even a novice), but I think it might help. The code is below.

diff -u zend-parser.y.orig zend-parser.y
--- zend-parser.y.orig  Fri Oct 27 09:35:35 2000
+++ zend-parser.y       Fri Oct 27 09:38:30 2000
@@ -414,12 +414,15 @@
 ;
 
 
+new_object:
+               T_NEW class_name { do_extended_fcall_begin(CLS_C); do_begin_new_object(&$1, &$2 CLS_CC); } ctor_arguments { do_end_new_object(&$$, &$2, &$1, &$4 CLS_CC); do_extended_fcall_end(CLS_C);}
+
 expr_without_variable:
                T_LIST '(' { do_list_init(CLS_C); } assignment_list ')' '=' expr { do_list_end(&$$, &$7 CLS_CC); }
        |       cvar '=' expr           { do_end_variable_parse(BP_VAR_W, 0 CLS_CC); do_assign(&$$, &$1, &$3 CLS_CC); }
        |       cvar '=' '&' w_cvar     { do_end_variable_parse(BP_VAR_W, 0 CLS_CC); do_assign_ref(&$$, &$1, &$4 CLS_CC); }
        |       cvar '=' '&' function_call { do_end_variable_parse(BP_VAR_W, 0 CLS_CC); do_assign_ref(&$$, &$1, &$4 CLS_CC); }
-       |       T_NEW class_name { do_extended_fcall_begin(CLS_C); do_begin_new_object(&$1, &$2 CLS_CC); } ctor_arguments { do_end_new_object(&$$, &$2, &$1, &$4 CLS_CC); do_extended_fcall_end(CLS_C);}
+       |       cvar '=' new_object { do_end_variable_parse(BP_VAR_W, 0 CLS_CC); do_assign_ref(&$$, &$1, &$3 CLS_CC); }
        |       cvar T_PLUS_EQUAL expr  { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 CLS_CC); }
        |       cvar T_MINUS_EQUAL expr { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 CLS_CC); }
        |       cvar T_MUL_EQUAL expr           { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_MUL, &$$, &$1, &$3 CLS_CC); }

 [2000-10-27 18:41 UTC] danjrod at terra dot es
Another option I have not mentioned in the previous "new comment" is having "new" support the "&" sintax.

$a = &new object_t()

And have then

  cvar = new_object .... do_assign( ...)
 |cvar = '&' new_object ... do_assign_ref(...)

But I still think that the constructor should always return a reference to the created object and not to a copy of the object as in my example code, this can be passed around and around from within the constructor.

Cheers
 [2000-12-06 16:53 UTC] waldschrott@php.net
fixed in cvs, you can use the following now:
$foo =& new barfoo();

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC