Получить дочерние объекты - PullRequest
       11

Получить дочерние объекты

1 голос
/ 02 сентября 2011

Я хочу таблицу комментариев примерно так

id | comment | parent_id
--------------------------
1    text1        0
2    text2        1
3    text3        2
4    text4        3
5    text5        3
6    text6        5

Я хочу построить массив, отображающий иерархию родителей и детей. Дерево должно возвращаться на неопределенное количество поколений. Я не хочу использовать вложенные циклы foreach, так как я не уверен, насколько они глубоки. Вот почему я здесь, я не уверен в лучшей практике для такой проблемы. Я также хочу отобразить глубину в массиве. Ниже приведен пример. Это на самом деле не относится к таблице выше, но, надеюсь, даст вам представление о том, что мне нужно.

array(
    "depth"=> 4
    "parent" => array(
        "id"=> 1,
        "comment" => "sometext1"
        "child_count" => 2,
        "children" => array(
            0 => array(
                "id" => 2
                "comment" => "sometext2",
                "child_count" => 0,
                "children" => null
            ),
            1 => array(
                "id" => 3
                "comment" => "sometext3"
                "child_count" => 1,
                "children" => array(
                    0 => array(
                        "id" => 2
                        "comment" => "sometext2",
                        "child_count" => 2,
                        "children" => array(
                            0 => array(
                                "id" => 2
                                "comment" => "sometext2",
                                "child_count" => 0,
                                "children" => null
                            ),
                            1 => array(
                                "id" => 2
                                "comment" => "sometext2",
                                "child_count" => 1,
                                "children" => array(
                                    "id" => 2
                                    "comment" => "sometext2",
                                    "child_count" => 0,
                                    "children" => null
                                )
                            )
                    )
                )
            )
        )
    )
)

Я собирался использовать foreach и делать SQL-оператор для извлечения родительских / дочерних объектов. т.е.

$sql = "SELECT * FROM comments WHERE parent = $parent_id";

Я на самом деле не ищу код для всего этого, просто решение псевдокода.

Ответы [ 2 ]

1 голос
/ 02 сентября 2011

Это легко сделать в PHP ... Для этого вам понадобятся два массива и два , в то время как циклы.

Этот код сделает дерево таким, каким вы хотели, для неопределенной глубины и количества детей.

Вставить в рабочий код.

Используя ссылки, давайте представим, что все сохранено в массиве $ data с такой структурой: (id, comment, parent_id) где parent_id указывает на id .

Код для построения дерева.

$tree = array();
reset($data);
while (list($k, $v) = each($data))
    if (0 == ($pid = $v['parent_id']))
        $tree[$k] =& $data[$k]; else
        $data[$pid]['children'][$k] =& $data[$k];

И для генерации глубины и количества дочерних элементов.

reset($data);
while (list($k, $v) = each($data))
    if (0 != $v['parent_id'])
    {
        $ref =& $data[$k];
        $depth = 0;
        do
        {
            if ($depth) $ref =& $data[$ref['parent_id']];
            $dre =& $ref['depth'];
            if (!isset($dre) || $dre <= $depth) $dre =  $depth++;
            if (isset($ref['children']))
                $ref['child_count'] = count($ref['children']);
                else
            {   
                $ref['child_count'] = 0;
                $ref['children'] = null;
            }   
        }   
        while ($ref['parent_id']);
    }

Весь мой код был написан на лету и даже не проверен, поэтому, если есть какие-либо ошибки, пожалуйста, простите меняеееееееее !!!!!!!!!!! ← Забудьте об этом, я пробовал , исправил пару проблем и теперь работает отлично.

Примечание

Чтобы этот код работал, индекс каждого элемента должен быть равен его идентификатору.

Массив, который я использовал, чтобы попробовать код.

$data = array(
    '1' => array('id' => '1', 'comment' => 'a', 'parent_id' => 0),
    '2' => array('id' => '2', 'comment' => 'b', 'parent_id' => 0),
    '3' => array('id' => '3', 'comment' => 'c', 'parent_id' => 1),
    '4' => array('id' => '4', 'comment' => 'd', 'parent_id' => 1),
    '5' => array('id' => '5', 'comment' => 'e', 'parent_id' => 2),
    '6' => array('id' => '6', 'comment' => 'f', 'parent_id' => 2),
    '7' => array('id' => '7', 'comment' => 'g', 'parent_id' => 5),
    '8' => array('id' => '8', 'comment' => 'h', 'parent_id' => 7)
    );
1 голос
/ 02 сентября 2011

Это проблема, когда вы используете список смежности для попытки извлечь все дочерние узлы в иерархии.Он просто не очень хорошо справляется с рекурсией, если вы используете mysql.(Oracle это другое дело).

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

Например, вы говорите, что хотите получить все дочерние узлы.Что ж, тогда вы, вероятно, должны использовать nested set models вместо или в дополнение к adjacency list.

Взгляните на некоторые из этих ресурсов ...

Есть ли простой способ запроса дочерних узлов?

Идеявложенного набора, это то, что вы сохраняете значения ребер lft и right узла, что означает, что извлечение любых дочерних узлов невероятно просто, потому что вы просто выбираете узлы, у которых значение lft больше целевогозначение узлов lft и меньше значения rgt.

Как только вы получите свой набор результатов, создание структуры массива будет простым.

См. Здесь: http://en.wikipedia.org/wiki/Nested_set_model

Как только вы получите свои результаты, взгляните на этот вопрос, который я задал год или около того назад, и это именно то, что вы хотите. PHP> Формирование многомерного массива из плоского массива модели вложенного множества

Пример

id | comment | parent_id  |   lft    |    rgt   |
-------------------------------------------------
1    World        null         1           12
2    Europe        1            2           11
3    England       2            3           10
4    Kent          3            4           5
5    Devon         3            6           9
6    Plymouth      5            7           8
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...