Bug #66200 [Nab]: the new operator DON'T returns a reference automatically

From: Date: Mon, 02 Dec 2013 09:55:22 +0000
Subject: Bug #66200 [Nab]: the new operator DON'T returns a reference automatically
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-183046@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=66200&edit=1 ID: 66200 User updated by: erwan dot oger35 at gmail dot com Reported by: erwan dot oger35 at gmail dot com Summary: the new operator DON'T returns a reference automatically Status: Not a bug Type: Bug Package: Class/Object related PHP Version: 5.4.22 Block user comment: N Private report: N New Comment: Hi thanks for your answer. In first I'm agree with you : << $b versus $this: Two variables, both referring to the same object. However while they have the same value the two are not the same variable like $a and $a2 were, so setting $b=null does not affect the "$this" that was passed to ObjHandler. A reference remains until the end of the script. >> However, it's my problems. When I read << "As of PHP 5, the new operator returns a reference automatically" >>, I understand that the two ARE the same variable: _______________ _______________________ $this ------->| ID |------>| B OBJECT | $b ------->|_______________| |_______________________| but in fact, it's this is : _______________ _______________________ $this ------->| ID_1 |------>| | |_______________| | | _______________ | B OBJECT | $b ------->| ID_2 |------>| | |_______________| |_______________________| And the goal of ObjHandler's goal it's to destruct all objects (update in db) in case of error (even fatale). So I need only one reference on this object when I want they'll be destructed only once. Actually I need a binding structure, as this singleton example : class MyClass { private static $_instance = null; private $isDestructed; // ************************* // BGN METHODES DE SINGLETON public static function &getInstance () { if ( is_null(self::$_instance) ) { self::$_instance =& self::create(); } return self::$_instance; } // ********************* // BGN CONSTRUCT METHODS private static function &create ( ) { $instance = new static(); ObjHandler::link($instance); return $instance; } private function __construct () { $this->temps_debut=microtime(true); $this->isDestructed = false; } private function __clone(){} // END CONSTRUCT METHODS // ********************* // END METHODES DE SINGLETON // ************************* // ******************** // BGN DESTRUCT METHODS public static function kill ( self &$instance ) { if ( ObjHandler::unlink($instance) ) { $instance = null; return true; } return false; } private function __destruct () { if ( !$this->isDestructed ) { $this->isDestructed = true; // *** TODO : INSTRUCTIONS *** } } // END DESTRUCT METHODS // ******************** // OTHER METHODS ... } So, even it's not a bug, I'll continue to believe it's not a good thing, which should be improved... Thanks. Previous Comments: ------------------------------------------------------------------------ [2013-11-29 13:25:26] requinix@php.net Looks like the correct behavior to me: an object reference is not the same thing as a variable reference. A variable has data associated with the variable itself, and one of those pieces of data is what the value is. An object reference is where the "what the value is" is the same for multiple variables, however the "data associated with the variable itself" is different for each. A variable reference will have both variables be using the same "data associated with the variable itself" (and thus the same "what the value is"). Shortest and simplest explanation I can come up with right now. $a2 = &$a: $a and $a2 are essentially the same variable, and setting $a=null destroys the only copy of the A instance (also affecting $a2 along the way). The assignment did not break the $a/$a2 link but rather changed the value that the two share. $b versus $this: Two variables, both referring to the same object. However while they have the same value the two are not the same variable like $a and $a2 were, so setting $b=null does not affect the "$this" that was passed to ObjHandler. A reference remains until the end of the script. ObjHandler::link($a): Because the method's $obj parameter is passed by-reference, you'll get the same behavior with that as you would with the $a2 = &$a you had before - except this time it's $obj = &$a. I don't know the purpose of the ObjHandler but I'm sure that link()'s $obj should not be by-reference. ------------------------------------------------------------------------ [2013-11-29 10:25:30] erwan dot oger35 at gmail dot com Note that even you change : "$a2 = &$a;" by : "ObjHandler::link($a);" it returns the same result !! ------------------------------------------------------------------------ [2013-11-29 10:04:34] erwan dot oger35 at gmail dot com Description: ------------ --- From manual page: http://www.php.net/language.operators.assignment --- "As of PHP 5, the new operator returns a reference automatically, so assigning the result of new by reference results in an E_DEPRECATED message in PHP 5.3 and later, and an E_STRICT message in earlier versions." Test script: --------------- <?php class A { private $name; private $counter; public function __construct ( $name ) { $this->name = $name; $this->counter = 0; } public function __destruct () { echo __METHOD__. ' : '. $this->name . ' ('.(++$this->counter).')<br/><br/>'.PHP_EOL.PHP_EOL; } } class B { private $name; private $counter; public function __construct ( $name ) { $this->name = $name; $this->counter = 0; ObjHandler::link($this); } public function __destruct () { echo __METHOD__. ' : '. $this->name . ' ('.(++$this->counter).')<br/><br/>'.PHP_EOL.PHP_EOL; } } class ObjHandler { private static $objLinked = array(); public static function link ( &$obj ) { self::$objLinked[] = &$obj; } } $a = new A('a'); $a2 = &$a; $a = null; $b = new B('b'); $b = null; Expected result: ---------------- A::__destruct : a (1) B::__destruct : b (1) FIN Actual result: -------------- A::__destruct : a (1) FIN B::__destruct : b (1) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=66200&edit=1

« previous php.bugs (#183046) next »