Как вытащить внуков из базы данных - PullRequest
2 голосов
/ 07 декабря 2009

Я хочу вытащить пункты меню из MySQL.

Main menu           id=1, parentid=0
-Contact us         id=2, parentid=1
-Music              id=3, parentid=1
 --Rock             id=8, parentid=3
 --Classic          id=9, parentid=3
-Car                id=4, parentid=1
  --Toyota          id=5, parentid=4,
  --Ford            id=6, parentid=4,
  --Honda           id=7, parentid=4

Other menu          id=10, parentid=0
-Othermain          id=11, parentid=10
  --submenu         id=12, parentid=11

etc.

Я могу вытащить данные с id = 1 до 4 и отобразить их как "... где parentid = 1" и т. Д. Однако это вытаскивает только верхний уровень.

Но я хочу также извлечь все данные, включая подменю для каждого меню (главного меню).

Может кто-нибудь сказать мне, как написать запрос в MySQL для этого, пожалуйста?

Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 07 декабря 2009

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

решение memcache

function generateTree($parentid = 0, &$tree) {
    $sql = sprintf('SELECT * FROM navigation WHERE parentid = %d', $parentid);
    $res = $this->db->results($sql);
    if ($res) {
        foreach ($res as $r) {
            // push found result onto existing tree
            $tree[$r->id] = $r;
            // create placeholder for children
            $tree[$r->id]['children'] = array();
            // find any children of currently found child
            $tree = generateTree($r->id, $tree[$r->id]['children']);
        }
    }
}

function getTree($parentid) {
    // memcache implementation
    $memcache = new Memcache();
    $memcache->connect('localhost', 11211) or die ("Could not connect"); 
    $tree = $memcache->get('navigation' . $parentid);
    if ($tree == null) {
        // need to query for tree
        $tree = array();
        generateTree($parentid, $tree);

        // store in memcache for an hour
        $memcache->set('navigation' . $parentid, $result, 0, 3600);
    }
    return $tree;
}

// get tree with parentid = 0
getTree(0);

решение без memcache

function generateTree($parentid = 0, &$tree) {
    $sql = sprintf('SELECT * FROM navigation WHERE parentid = %d', $parentid);
    $res = $this->db->results($sql);
    if ($res) {
        foreach ($res as $r) {
            // push found result onto existing tree
            $tree[$r->id] = $r;
            // create placeholder for children
            $tree[$r->id]['children'] = array();
            // find any children of currently found child
            $tree = generateTree($r->id, $tree[$r->id]['children']);
        }
    }
}

// get tree with parentid = 0
$tree = array();
$parentid = 0;
generateTree($parentid, $tree);

// output the results of your tree
var_dump($tree); die;

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

1 голос
/ 07 декабря 2009

Самый быстрый способ - извлечь все элементы из таблицы и построить дерево меню на стороне кода.

...