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
 [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: Wed Oct 30 22:01:28 2024 UTC