.
Это готовое решение
Готовое решение для тех, кто задался вопросом: как вывести хлебные крошки на сайте.
Имеем:
Таблица documents, где есть 4 поля:
id, parent_id, name, alias
Это не Nested Sets, не Materialized Path.
Имеем только то что имеем.
Задача:
Получить хлебные крошки от корня до текущего раздела.
Сделать все за один легкий запрос на клиенте.
Для этого используем хранимую процедуру.
Я искал в сети примеры. Все они были монстроподобны.
Вобщем наглядевшись на всякие страсти,
решил сделать это короче, красивее и адаптивнее.
Под спойлером результат:
Спойлер (Отобразить)CODE ( SQL):
скопировать код в буфер обмена
DELIMITER $$ DROP PROCEDURE IF EXISTS get_breadcrumbs$$ CREATE PROCEDURE get_breadcrumbs(IN current_id BIGINT(20), show_home TINYINT(1)) READS SQL DATA BEGIN DECLARE buff_id BIGINT(20); DECLARE buff_parent_id BIGINT(20); DECLARE done_search TINYINT(1); DECLARE current_depth BIGINT(20); SET done_search = 0; SET current_depth = 0; SET buff_id = NULL; CREATE TEMPORARY TABLE breadcrumbs (id BIGINT(20), depth BIGINT(20)) ENGINE = MEMORY; findloop : WHILE done_search = 0 DO SELECT id, parent_id INTO buff_id, buff_parent_id FROM documents WHERE id = current_id; IF buff_id IS NULL THEN IF show_home != 0 THEN SELECT id, parent_id INTO buff_id, buff_parent_id FROM documents WHERE alias = '/'; IF buff_id IS NOT NULL THEN INSERT INTO breadcrumbs (id, depth) VALUES(buff_id, current_depth); END IF; END IF; SET done_search = 1; LEAVE findloop; END IF; INSERT INTO breadcrumbs (id, depth) VALUES(buff_id, current_depth); SET current_id = buff_parent_id; SET current_depth = current_depth + 1; SET buff_id = NULL; END WHILE findloop; SELECT d.id, d.parent_id, d.name, d.alias, b.depth FROM breadcrumbs b INNER JOIN documents d ON d.id = b.id ORDER BY b.depth DESC; END$$ DELIMITER ;
Процедура принимает два аргумента:
1) ID текущего документа, до которого нужно строить крошки.
2) 1 или 0 - добавить главную страницу в начало результата или нет.
Использование предельно просто:
После фетча результатов получаем массив вида:
Спойлер (Отобразить)CODE ( dump):
скопировать код в буфер обмена
array(4) { [0]=> array(5) { ["id"]=> string(1) "2" ["parent_id"]=> string(1) "0" ["name"]=> string(14) "Каталог" ["alias"]=> string(8) "/catalog" ["depth"]=> string(1) "3" } [1]=> array(5) { ["id"]=> string(2) "20" ["parent_id"]=> string(1) "2" ["name"]=> string(28) "Товары для дома" ["alias"]=> string(24) "/catalog/tovary-dla-doma" ["depth"]=> string(1) "2" } [2]=> array(5) { ["id"]=> string(2) "32" ["parent_id"]=> string(2) "20" ["name"]=> string(32) "Товары для уборки" ["alias"]=> string(42) "/catalog/tovary-dla-doma/tovary-dla-uborki" ["depth"]=> string(1) "1" } [3]=> array(5) { ["id"]=> string(2) "78" ["parent_id"]=> string(2) "32" ["name"]=> string(53) "Тряпка половая из микрофибры" ["alias"]=> string(96) "/catalog/tovary-dla-doma/tovary-dla-uborki/tryapka-polovaya-iz-mikrofibry" ["depth"]=> string(1) "0" } }
З.Ы.: Для тех кто использует не mysqli - имейте ввиду, процедура возвращает не один результат, а два: саму выборку и статус успеха.
Нам нужен только первый результат.
Кажется это не будет работать на старом драйвере без i в конце, увы.
Переезжайте на mysqli*
|