Php 类内带有foreach的递归函数更改了不应使用的公共值';T

Php 类内带有foreach的递归函数更改了不应使用的公共值';T,php,class,recursion,foreach,hierarchical,Php,Class,Recursion,Foreach,Hierarchical,好吧,我真的被这个搞砸了。我希望你能帮助我 我有我的类,用于管理分层数据。输入是具有以下结构的普通数组(仅为示例): 我通过以下方式向类输入数据: $Hierarchical = new Hierarchical; $Hierarchical->plain = $list; 然后我有一个公共函数(createTree)来创建列表的多维数组表示。它工作得很好。它可以返回结果或将其存储在$this->tree中 正如你所看到的,这很简单。它调用私有函数iterateTree,这是递归函数 c

好吧,我真的被这个搞砸了。我希望你能帮助我

我有我的类,用于管理分层数据。输入是具有以下结构的普通数组(仅为示例):

我通过以下方式向类输入数据:

$Hierarchical = new Hierarchical;
$Hierarchical->plain = $list;
然后我有一个公共函数(
createTree
)来创建列表的多维数组表示。它工作得很好。它可以返回结果或将其存储在
$this->tree

正如你所看到的,这很简单。它调用私有函数iterateTree,这是递归函数

class Hierarchical {

    public $plain = array();
    public $tree = array();

    public function createTree($parentId=0, $return=false) {

    $tree = $this->iterateTree($parentId);

    if(!$return) {
        $this->tree = $tree;
    } else {
        return $tree;
    }

    }


    private function iterateTree($parentId) {

    $resArray = array();

    foreach($this->plain as $item) {

        if($item->parentId == $parentId) {

            $children = $this->iterateTree($item->id);

            if( count($children) > 0 ) {
                $item->children = $children;
            }

            $resArray[] = $item;

        }

    }

    return $resArray;

    } 

}
到目前为止还不错。它很好用

但是…在调用
createTree()
之后,当我想使用
$this->plain时,问题出现了。它不返回原始数据集,而是返回原始输入之间的某种混合,并附加其所有子项(类似于
$this->tree

我不明白为什么要更改
$this->plain
的内容,也不知道在使用的两个函数中我都在更改它的内容

我尝试在
foreach
之后取消设置
foreach
中的变量,甚至将原始数组作为参数传递,并且在递归函数中根本不使用
$this->plain
。什么都没用

我也使用类中任何其他可能改变其值的函数


这完全是一片迷雾

foreach
循环中
$item
将是对数组中对象的引用,因此您正在更改行中的同一对象

$item->children = $children;
这将影响原始数组
$list
$This->plain
中引用的对象


一种解决方案可能是在foreach循环中克隆
$item

添加到Doug的答案中,尽管手册中说“对象不是通过引用传递的”(http://www.php.net/manual/en/language.oop5.references.php)相反,它可能有助于将对象视为与任何可能“包含”的变量完全分离的实体它们,它们实际上到处都是通过引用传递的

class testClass
{
    public $var1 = 1;
}

function testFunc($obj)
{
    $obj->var1 = 2;
}


$t = new testClass;
testFunc($t);
echo $t->var1; // 2

所以当你做
$item->children=$children$plain
数组中的每个原始对象。

根据Doug的回答,正确的函数是:(添加
$itemAux=clone$item


杰出的非常感谢你。
class testClass
{
    public $var1 = 1;
}

function testFunc($obj)
{
    $obj->var1 = 2;
}


$t = new testClass;
testFunc($t);
echo $t->var1; // 2
private function iterateTree($parentId) {

    $resArray = array();

    foreach($this->plain as $item) {

        $itemAux = clone $item;

        if($itemAux->parentId == $parentId) {

            $children = $this->iterateTree($itemAux->id);

            if( count($children) > 0 ) {
                $itemAux->children = $children;
            }

            $resArray[] = $itemAux;

        }

    }

    return $resArray;

}