PHP 4.0 Bug #7482 Updated: this is not reference in class constructor: Bug 6896 extension/correction

From: Date: Wed, 06 Dec 2000 21:53:19 +0000
Subject: PHP 4.0 Bug #7482 Updated: this is not reference in class constructor: Bug 6896 extension/correction
Groups: php.dev 
Request: Send a blank email to php-dev+get-40261@lists.php.net to get a copy of this message
ID: 7482 Updated by: waldschrott Reported By: danjrod@terra.es Status: Closed Bug Type: Class/Object related Assigned To: Comments: fixed in cvs, you can use the following now: $foo =& new barfoo(); Previous Comments: --------------------------------------------------------------------------- [2000-10-27 18:41:16] danjrod@terra.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-10-27 16:01:31] danjrod@terra.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-26 11:14:04] danjrod@terra.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. ?> --------------------------------------------------------------------------- Full Bug description available at: http://bugs.php.net/?id=7482

« previous php.dev (#40261) next »