neudor

log

Entries Comments



Конвертация дерева в nested sets

9 October, 2008 (11:17) | PHP | By: neudor

Я кодю кое-чего крупное на CakePHP. Ну то есть код с нуля, а базы кое-какие остались от прошлой системы. И есть в этих базах дерево категорий. Обычное иерархическое дерево, где у каждого элемента есть parent_id:

id	name		parent_id

1	first		0
2	second		0
3	third		1

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

Итак, на данном этапе сформировалась задача перевести существующее дерево к виду nested sets, а это значит у каждой записи в таблице проставить значения left и right. Гуглению было посвящено около часа. Сплошные вопросы, и ни одного работающего решения. Собственно такое положение и явилось причиной, по которой я выкладываю свою функцию. Вникайте.

$table = 'categories';
$number=1;

make_nested(0);

function make_nested($parent_id = 0) {
    global $db, $table, $number;
    $c = $db->selectCell("SELECT COUNT(*) from ".$table." \
    where parent_id=".$parent_id."");
    for($i=0; $i<$c; $i++) {
        $newrow = $db->selectRow("SELECT * FROM ".$table." \
        where parent_id=".$parent_id." order by sort, id \
        LIMIT $i, 1");

        $db->query("UPDATE `".$table."` SET lft=".$number." \
        WHERE id=".$newrow['id']."");
        $number++;

        make_nested($newrow['id']);

        $db->query("UPDATE `".$table."` SET rght=".$number." \
        WHERE id=".$newrow['id']."");
        $number++;
    }
}

Собственно функция — это как бы тот самый “червячок”, обходящий все вершины против часовой и размечающий их. Ничего сложного. Пользуйтесь и радуйтесь!

Похожие записи:

Write a comment




*
To prove that you're not a bot, enter this code
Anti-Spam Image