PHP 4.0 Bug #7482 Updated: this is not reference in class constructor: Bug 6896 extension/correction
| From: | waldschrott@php.net | 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