normally we would use it like that:
class TestClass
{
public $t;
public function set(stdClass &$t)
{
$this->t = &$t;
}
}
$obj = new stdClass();
$obj->fromOUTSIDE = 1;
$test = new TestClass();
$test->set($obj);
var_dump($test);
this results in the desired result:
object(TestClass)#2 (1) {
["t"]=>
&object(stdClass)#1 (1) {
["fromOUTSIDE"]=>
int(1)
}
}
notice the & character, as its a reference. So far so good!
But what if the __get
magic method creates this?
class TestClass
{
public function __get(string $propertyName)
{
$xx = new stdClass();
$xx->fromGET = 1;
$this->t = &$xx;
return $this->t;
}
}
$test = new TestClass();
$test->t;
var_dump($test);
the reference character disappeared!
object(TestClass)#1 (1) {
["t"]=>
object(stdClass)#2 (1) {
["fromGET"]=>
int(1)
}
}
how to make it referenced? Even using the public function &__get form still no work!
EDIT:
So a basic code:
class X
{
public stdClass $t;
public function __construct(stdClass &$t)
{
$this->t = &$t;
}
}
$t = new stdClass();
$t->TTTT = 1;
$X = new X($t);
var_dump($t);echo "rn";
var_dump($X->t);echo "rn";
$t = new stdClass();
$t->TTTT = 2;
var_dump($t);echo "rn";
var_dump($X->t);echo "rn";
see, it results #1, #1, #3, #1 because renewing the old object wont be affected the object inside the X
.
If I do:
<?php
class X
{
public stdClass $t;
public function __construct(stdClass &$t)
{
$this->t = &$t;
}
}
$t = new stdClass();
$t->TTTT = 1;
$X = new X($t);
var_dump($t);echo "rn";
var_dump($X->t);echo "rn";
$t = new stdClass();
$t->TTTT = 2;
var_dump($t);echo "rn";
var_dump($X->t);echo "rn";
gives the desired result, #1, #1, #3, #3. But what if $t
property doesn’t exist? Maybe __get
has to create it or obtain from an object-container. And this is where I can’t solve it.
2
Answers
I’m not 100% on this, but if I understand your question correctly I believe your code actually does what you expect it to do. However creating a reference is not nessecary.
There is only one reference to the
stdClass
object in this case. Therefor the representation with the ampersand is not nessesary.If you add another reference is should appear:
Your
t
property will not be a reference because you declare yourstdClass
inside the__get
function. Which means that your$xx
will be destroy when the execution of the__get
function is finished.How can you do it so ?
2 options:
global
variable:Result (https://onlinephp.io/c/c9b92):
$xx
outside the__get
function:Result (https://onlinephp.io/c/a99f3):
Futhermore if you change option 2 and add
unset($test->xx)
, you will see that you loose the reference as in your example.Result (https://onlinephp.io/c/801b8):