递归函数里面的类与foreach更改公共值,它不应该 [英] Recursive function inside class with foreach changes public value where it shouldn't

查看:145
本文介绍了递归函数里面的类与foreach更改公共值,它不应该的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我真的很抱歉。我希望你能帮助我。

Ok, I'm really stucked with this. I hope you can help me.

我有我的类,用于管理分层数据。输入是一个具有以下结构的平面数组(只是一个例子):

I have my class, used to manage hierarchical data. The input is a plain array with the following structure (just an example):

$list = array(
(object) array('id' => 1, 'nombre' => 'Cámaras de fotos', 'parentId' => null),
(object) array('id' => 2, 'nombre' => 'Lentes', 'parentId' => null),
(object) array('id' => 3, 'nombre' => 'Zoom', 'parentId' => 2),
(object) array('id' => 4, 'nombre' => 'SLR', 'parentId' => 1),
(object) array('id' => 5, 'nombre' => 'Primarios', 'parentId' => 2),
(object) array('id' => 6, 'nombre' => 'Sensor APS-C', 'parentId' => 4),
(object) array('id' => 7, 'nombre' => 'Full-frame', 'parentId' => 4),
(object) array('id' => 8, 'nombre' => 'Flashes', 'parentId' => null),
(object) array('id' => 9, 'nombre' => 'Compactas', 'parentId' => 1)
);

我以这种方式将数据输入类:

I input the data to the class this way:

$Hierarchical = new Hierarchical;
$Hierarchical->plain = $list;

然后我有一个公共函数( createTree )创建列表的多维数组表示。它工作完美。它可以返回结果或将它存储在 $ this-> tree 中。

Then I have a public function (createTree) to create a multidimensional array representation of the list. It works perfectly. It can return the result or store it inside $this->tree.

如您所见,这非常简单。它调用私有函数 iterateTree ,这是递归函数。

As you can see, this is very simple. It calls private function iterateTree, which is the recursive function.

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;

    } 

}

好。它工作正常。

但是... 当我想使用 $ this-> plain 调用 createTree()后。不是返回原始数据集,而是返回原始输入之间的某种混合,其中所有的子代都附加(类似于 $ this-> tree )。

BUT... The problem appears when I want to use $this->plain after calling createTree(). Instead of returning the original dataset, it returns some kind of mix between the original input, with all their children appended (similar to $this->tree).

我不知道为什么 $ this-> plain 的内容正在更改,这两个函数使用我改变它的内容。

I can't figure out why the content of $this->plain is being changed, neither in the both functions used I'm changing it's content.

我已经尝试取消了 foreach 中的变量, foreach ,甚至将原始数组作为参数传递,而不是在递归函数中使用 $ this-> plain 。没有什么工作。

I've tried unseting the variables inside the foreach, after the foreach, even passing the original array as an argument and not using $this->plain at all inside the recursive function. Nothing worked.

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

I'm also not using any other function inside the class that could change it's value.

这是一个完全的mistery!

It's a total mistery!

推荐答案

$ c> foreach loop $ item 将引用数组中的对象,因此您要更改该行中的同一对象



In your foreach loop $item will be a reference to the object in the array, so you are changing that same object in the line

$item->children = $children;

这将影响原始数组中引用的对象 $ list $ this-> plain

This will affect the object referred to in the original arrays $list and $this->plain.

一个解决方案可能是克隆 $ item

One solution may be to clone $item within your foreach loop.

这篇关于递归函数里面的类与foreach更改公共值,它不应该的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆