Vladimir Despotovic Vladimir Despotovic -4 years ago 34
PHP Question

PHP 7 - references lost during array property traversal

I want to find an array property's element, which is also an array and I want to append more members to it. I can append it, but somehow the references seem to be lost and all I'm left is a copy. The original array is unaffected. This is my code:

<?php

class CategoryTree
{
var $tree;

public function CategoryTree() {
// First element of the array represents the name of the category, so to iterate children, we have to go from index 1
$tree=$this->tree;
$tree["root"] = array();
}

private function &getCategoryWithNameInSubtree($name, &$subTreeRoot) {

if (count($subTreeRoot) == 0) return false; // There are no branches coming from this root

// So, the subtree has some branches to traverse...
foreach ($subTreeRoot as $branchName => &$branch) {
if ($branchName == $name) { // Search is over - this branch has the specified name
return $subTreeRoot[$branchName];
} else {
$subTreeSearchResult = $this->getCategoryWithNameInSubtree($name, $branch);
if($subTreeSearchResult) {
return $subTreeSearchResult;
} else {
//If we have reached this, it means the name was not found in that branch
}
}

}

//We traversed all branches and no name was equal to the specified name
return false;

}

public function &getCategoryWithName($name) {
$tree=&$this->tree;
return $this->getCategoryWithNameInSubtree("seconda", $tree);

}
}


$c = new CategoryTree();

$c->tree=array("prima" => array("prima-prima" => [], "prima-seconda" => [], "prima-terza" => []),
"seconda" => array("seconda-prima" => [], "seconda-seconda" => [], "seconda-terza" => []),
"terza" => array("terza-prima" => [], "terza-seconda" => [], "terza-terza" => []),
);


$seconda=$c->getCategoryWithName("seconda");
$seconda[] = "added";
print "cat is: <pre>"; print_r($seconda); print "</pre>";

print "ct is: <pre>"; print_r($c); print "</pre>";


I want the change to "seconda" to persist in the original property $c->tree, but they are not. The references are lost somewhere. Do you know how is this properly set up? I use a recursion off course, for traversal, so that might be a problem, but I highly doubt it. Can you help out? Thanks anyway. This would clear out my confusion about PHP references.

Answer Source

Add reference symbol before element that should be referenced

$seconda = &$c->getCategoryWithName("seconda");
           ^ here

Just stick to simple rule:

$arr = Array();
$copy = $arr; // copy
$reference = &$arr; // reference

This is how references works with functions/classes

public function getArray() // always copy
$arr = $class->getArray() // copy
$arr = &$class->getArray() // copy

public function &getArray() // returns reference
$arr = $class->getArray() // copy
$arr = &$class->getArray() // reference
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download