PHP: рекурсивно получить детей родителей - PullRequest
3 голосов
/ 01 марта 2010

У меня есть функция, которая получает идентификаторы всех потомков родителя из моей БД. Итак, если я посмотрю на id 7, он может вернуть массив с 5, 6 и 10. То, что я затем хочу сделать, это рекурсивно найти дочерние элементы этих возвращенных идентификаторов и так далее, до конечной глубины дочерних элементов.

Я пытался написать функцию для этого, но меня смущает рекурсия.

function getChildren($parent_id) {
    $tree = Array();
    $tree_string;
    if (!empty($parent_id)) {
        // getOneLevel() returns a one-dimentional array of child ids
        $tree = $this->getOneLevel($parent_id);
        foreach ($tree as $key => $val) {
            $ids = $this->getChildren($val);
            array_push($tree, $ids);
            //$tree[] = $this->getChildren($val);
            $tree_string .= implode(',', $tree);
        }

        return $tree_string;
    } else {
        return $tree;
    }

}//end getChildren()

После запуска функции мне бы хотелось, чтобы она возвращала одномерный массив всех найденных дочерних идентификаторов.

Ответы [ 3 ]

6 голосов
/ 20 апреля 2010

Это прекрасно работает для меня:

function getOneLevel($catId){
    $query=mysql_query("SELECT categoryId FROM categories WHERE categoryMasterId='".$catId."'");
    $cat_id=array();
    if(mysql_num_rows($query)>0){
        while($result=mysql_fetch_assoc($query)){
            $cat_id[]=$result['categoryId'];
        }
    }   
    return $cat_id;
}

function getChildren($parent_id, $tree_string=array()) {
    $tree = array();
    // getOneLevel() returns a one-dimensional array of child ids        
    $tree = $this->getOneLevel($parent_id);     
    if(count($tree)>0 && is_array($tree)){      
        $tree_string=array_merge($tree_string,$tree);
    }
    foreach ($tree as $key => $val) {
        $this->getChildren($val, &$tree_string);
    }   
    return $tree_string;
}

Позвоните на getChildren(yourid); Затем он вернет полный массив потомков для данного узла / родителя.

3 голосов
/ 01 марта 2010

Модель вложенного набора вместо модели списка смежности


Могу ли я предложить вам хранить ваши узлы в вашей базе данных под NSM вместо ALM?

Обратите внимание, что с ALM (что и используется) получить дочерние узлы довольно сложно, это возможно, но требует дополнительной работы. Если вы используете модель вложенного множества, выбирая дочерний узел или все узлы, или даже находя глубину всех узлов, можно выполнить один SQL-запрос.

Я надеюсь, что это проливает некоторый свет на то, как вы могли бы решить свою проблему, если вы еще молоды в разработке вашего проекта, переключение сейчас избавит вас от многих головных болей позже.

1 голос
/ 20 апреля 2010

Вместо array_push($tree, $ids); попробуйте $tree = array_merge($tree, $ids);. Убейте $tree_string .= implode(',', $tree); и просто return $tree. (Один раз)

function getChildren($parent_id) {
    $tree = Array();
    if (!empty($parent_id)) {
        $tree = $this->getOneLevel($parent_id);
        foreach ($tree as $key => $val) {
            $ids = $this->getChildren($val);
            a$tree = array_merge($tree, $ids);
        }
    }
    return $tree;
}
...