Vladimir Despotovic
Vladimir Despotovic

Reputation: 3498

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.

Upvotes: 0

Views: 47

Answers (1)

Peter
Peter

Reputation: 16923

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

Upvotes: 1

Related Questions