I have an array I’m using as a stack to store a path through a tree. Each element points to a node in the tree and I want to pop the last element off and then set the object referred to by that element to null.
Basically:
$node = array_pop($path);
*$node = null;
assuming that PHP had a ‘*’ operator as C-ish languages do. Right now I have the ugly solution of starting at the parent node and remembering which child I took and then setting that to null as in:
if($goLeft) {
$parent->left = null;
} else {
$parent->right = null;
}
I say this is ugly because the array containing the path is created by a public function in my tree class. I’d like to expose the ability to work directly on the nodes in a path through the tree without exposing an implementation detail that addresses an idiosyncrasy (feature?) in PHP. ATM I need to include a boolean in the return value ($goLeft in this case) just so I can workaround an inability to dereference a reference.
This is the second time I’ve encountered this problem, so if anyone knows a way I can do something similar to the first block of code please share!
(EDIT)
After experimenting with many permutations of &’s and arrays, it turns out that the basic problem was that I had misinterpreted the reason for an error I was getting.
I tried
$a = ($x > $y) ? &$foo[$bar] : $blah;
and got ” syntax error, unexpected ‘&’ “. I interpreted this to mean that the problem was using the &-operator on $foo[$bar]. It actually turns out that the culprit is the ?-operator, as
if($x > $y) {
$a = &$foo[$bar];
} else {
$a = null;
}
works perfectly fine. I thus went on a wild goose chase looking for a workaround for a problem that didn’t exist. As long as I don’t break the chain of &’s, PHP does what I want, which is to operate on the object referred to by a variable (not the variable itself). Example
$a1 = new SomeClass;
$a2 = &$a1;
$a3 = &$a2;
$a4 = &$a3;
$a4 = 42; // This actually sets $a1 to 42
var_dump($a1); // Emits 42
What messed me up is that I thought objects are passed around by reference anyway (this is wrong), so I didn’t think the & was necessary if the expression resolved to an object. I mean:
class A {
public $b;
}
class B {}
$a = new A;
$a->b = new B;
$c1 = $a->b;
$c2 = &$a->b;
$c1 = 42; // Merely assigns 42 to $c1
$c2 = 42; // Assigns 42 to $a->b
It turns out that this exact issue is addressed at http://www.php.net/manual/en/language.oop5.references.php. Wish that had sunk in the first time I read it!
Very interesting question! I may have found a workaround: if you populate the array with object references, with the
&operator, you can destroy the original object by setting that array value toNULL. You have to operate on the array directly, instead of using a variable returned byarray_pop. After that you can pop the array to free that position (that would then contain aNULLvalue).This is what I mean (based on Rocket’s code):
http://codepad.org/3D7Lphde