Bug #66200 [Nab]: the new operator DON'T returns a reference automatically
| From: | requinix@php.net | Date: | Mon, 02 Dec 2013 11:10:02 +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-183047@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
Updated by: requinix@php.net
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:
I don't see what the improvement is supposed to be, but I assume the issue of "new not
returning references" has been solved? A couple final comments:
1. Object references and variable references are two different things, both under the
"references" umbrella. What you thought was supposed to happen is not the case, if for the
very simple reason that new returns an object and not a variable and thus it's not possible to
use variable references there.
2. I can't think of any way to guarantee that one object reference (of a particular instance)
exists during execution. Variable references would do it but you'd have to make sure that all
code uses them, which sounds like poor design, not to mention being a real pain.
If you need more help solving whatever your problem is, try a mailing list or forum. http://www.php.net/support.php
Previous Comments:
------------------------------------------------------------------------
[2013-12-02 09:55:21] erwan dot oger35 at gmail dot com
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.
------------------------------------------------------------------------
[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