Php вывод древовидной структуры

Построение дерева на php (вывод меню с неограниченной вложенностью)

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

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

Как делать не нужно

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

  1. Огромное кол-во запросов к базе данных
    Например, в интернет-магазине меню состоит из 300-т категорий и подкатегорий. Для вывода такого меню нужно 100-ни запросов, что очень сильно грузит сервер, и тормозит загрузку сайта.
  2. Заказчик не сможет сам добавлять уровень вложенности из системы управления
  3. Если заказчик попросит добавить новый уровень вложенности, придется потратить очень много времени и сил на это.

У нас был заказчик, который очень удивлялся высокой стоимости поддержки сайта, т.к. у него и вывод меню был сделан не правильно, и все остальное. И для веб мастера нужно было потратить много сил и времени, чтобы что-то исправить на сайте. В итоге он решил сделать себе новый сайт. Хотя стоимость сайта была достаточно высока, но она окупилась через какое-то время, за счет низкой стоимости поддержки сайта.

Читайте также:  Php вывод массива построчно

Как делать нужно

Нужно делать так, чтобы вложенность меню генерировалась автоматически, и было всего 1-о обращение к базе данных.

Построение и вывод дерева на php

Сейчас мы сделаем вывод дерева на примере структуры сайта нашей компании (ox2.ru). Мы постоим дерево следующего вида (3 уровня вложенности):

Подготовка базы данных

Для построения дерева на php нам нужна база данных следующего вида:

Первое поле id категории, оно уникально для каждой категории. Второе поле name – имя категории, третье полеparent_id – оно ссылается на id категории родителя.

Например, для раздела Тариф «Оптимальный» parent_id = 4, поскольку она является подкатегорией раздела с id равным 4-ем (Создание интернет магазина, а она имеет parent_id равным 2-ум, т.к. является 2-ым уровнем вложенности раздела Услуги). Если parent_id = 0, то это главная категория.

Вот дамп нашей базы данных:

-- -- База данных: `ox2.ru-test-base` -- CREATE DATABASE `ox2.ru-test-base` DEFAULT CHARACTER SET cp1251 COLLATE cp1251_general_ci; USE `ox2.ru-test-base`; -- -------------------------------------------------------- -- -- Структура таблицы `category` -- CREATE TABLE IF NOT EXISTS `category` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `parent_id` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `parent_id` (`parent_id`) ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=18 ; -- -- Дамп данных таблицы `category` -- INSERT INTO `category` (`id`, `name`, `parent_id`) VALUES (1, 'Главная', 0), (2, 'Услуги', 0), (3, 'Наши работы', 0), (4, 'Создание интернет магазина', 2), (5, 'Создание сайта', 2), (6, 'Продвижение сайта', 2), (13, 'Продвижение по позициям', 6), (7, 'Тариф «Оптимальный»', 4), (8, 'Тариф «Расширенный»', 4), (9, 'Тариф «Максимальный»', 4), (10, 'Сайт визитка', 5), (11, 'Фирменный сайт', 5), (12, 'Корпоративный сайт', 5), (14, 'Продвижение по трафику', 6), (15, 'Сроки и гарантии', 6), (16, 'Создание интернет магазина', 3), (17, 'Создание сайта', 3);

Вывод дерева на PHP

Поскольку много читателей не знакомы с PHP5, мы сделали 2 версии вывода меню (на PHP4 и на PHP5)

Для тех кто программирует на PHP5, пропустите следующий раздел

Вывод меню на PHP4

 return $result; > //В переменную $category_arr записываем все категории $category_arr = getCategory(); /** * Вывод дерева * @param Integer $parent_id - id-родителя * @param Integer $level - уровень вложености */ function outTree($parent_id, $level) < global $category_arr; //Делаем переменную $category_arr видимой в функции if (isset($category_arr[$parent_id])) < //Если категория с таким parent_id существует foreach ($category_arr[$parent_id] as $value) < //Обходим /** * Выводим категорию * $level * 25 - отступ, $level - хранит текущий уровень вложености (0,1,2..) */ echo "
" . $value["name"] . "
"; $level = $level + 1; //Увеличиваем уровень вложености //Рекурсивно вызываем эту же функцию, но с новым $parent_id и $level outTree($value["id"], $level); $level = $level - 1; //Уменьшаем уровень вложености > > > outTree(0, 0); ?>

Вывод меню на PHP5

_db = new PDO("mysql:dbname=ox2.ru-test-base;host=localhost", "root", ""); //В переменную $_category_arr записываем все категории (см. ниже) $this->_category_arr = $this->_getCategory(); > /** * Метод читает из таблицы category все сточки, и * возвращает двумерный массив, в котором первый ключ - id - родителя * категории (parent_id) * @return Array */ private function _getCategory() < $query = $this->_db->prepare("SELECT * FROM `category`"); //Готовим запрос $query->execute(); //Выполняем запрос //Читаем все строчки и записываем в переменную $result $result = $query->fetchAll(PDO::FETCH_OBJ); //Перелапачиваем массим (делаем из одномерного массива - двумерный, в котором //первый ключ - parent_id) $return = array(); foreach ($result as $value) < //Обходим массив $return[$value->parent_id][] = $value; > return $return; > /** * Вывод дерева * @param Integer $parent_id - id-родителя * @param Integer $level - уровень вложености */ public function outTree($parent_id, $level) < if (isset($this->_category_arr[$parent_id])) < //Если категория с таким parent_id существует foreach ($this->_category_arr[$parent_id] as $value) < //Обходим ее /** * Выводим категорию * $level * 25 - отступ, $level - хранит текущий уровень вложености (0,1,2..) */ echo "
" . $value->name . "
"; $level++; //Увеличиваем уровень вложености //Рекурсивно вызываем этот же метод, но с новым $parent_id и $level $this->outTree($value->id, $level); $level--; //Уменьшаем уровень вложености > > > > $tree = new TreeOX2(); $tree->outTree(0, 0); //Выводим дерево ?>

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

Комментарии (Написать комментарий)

    , то можно отказаться от $level и вывод сделать более красивым

Сергей [14.08.2015] Комментарий:
Спасибо, ваша статья помогла мне решить поставленную задачу. Скрипт написал правда свой, но идею с логикой частично позаимствовал у вас )

Иван [16.06.2015] Комментарий:
Спасибо за образец, ваш сайт помогает в освоении практики программирования.

Источник

Древовидные структуры данных в PHP на примере вложенных комментариев

Древовидные структуры данных в PHP на примере вложенных комментариев

Одной из самых распространенных структур данных в программировании является — дерево. Например, дерево комментариев, дерево каталогов, дерево категорий и т.д. Т.е. это абстракция окружает нас везде.

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

Код ниже может быть использован для вывода древовидных комментариев к статье:

// строит структуру дерево из простого списка
function buildTree(array &$list)
$tree = [];

// делаем группировку по идентификатору родителя
foreach ($list as $node) $tree[$node[‘parent_id’]][] = $node;
>

// рекурсивная функция, создающая вложенную (древовидную) структуру
$recursiveBuilder = function ($children) use (&$recursiveBuilder, $tree)

foreach ($children as $key => $child)
$child_id = $child[‘comment_id’];

if (isset($tree[$child_id])) $child[‘answers’] = $recursiveBuilder($tree[$child_id]);
>

Вот структура таблицы комментариев:

create table comments
(
comment_id int auto_increment primary key, — первичный ключ — id комментария
post_id int null, — id статьи
parent_id int default 0 null, — идентификатор родительского комментария
author varchar(100) default ‘Нет имени’ null,
created_at datetime default CURRENT_TIMESTAMP null,
text text null
)
comment ‘хранит все комментарии к статьям’

Создание вложенных комментариев:

// функция для работы с подключения к базе MySQL
function connection(string $host, string $db, string $user, string $pass, string $charset = ‘utf8’): \PDO
$dsn = «mysql:host=$host;dbname=$db;charset=$charset»;
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];

$pdo = new PDO($dsn, $user, $pass, $opt);

// подключаемся к базе
$connection = connection(‘127.0.0.1’, ‘comments_db’, ‘user’, ‘password’);

// выбираем все комментарии к статье с идентификатором 1
$stmt = $connection->query(‘SELECT * FROM comments WHERE post_id = 1’);
$comments = $stmt->fetchAll();

// строим дерево
$tree = buildTree($comments);

// выводим на печать
print_r($tree);

Вот таким образом можно создать дерево комментариев на PHP. Да и не только это. Например, с помощью функции buildTree(array) можно построить и каталог интернет-магазина и карту сайта.

Создано 22.07.2021 13:54:55

  • Михаил Русаков
  • Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

    Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
    Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

    Если Вы не хотите пропустить новые материалы на сайте,
    то Вы можете подписаться на обновления: Подписаться на обновления

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

    Порекомендуйте эту статью друзьям:

    Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

    1. Кнопка:
      Она выглядит вот так:
    2. Текстовая ссылка:
      Она выглядит вот так: Как создать свой сайт
    3. BB-код ссылки для форумов (например, можете поставить её в подписи):

    Комментарии ( 0 ):

    Для добавления комментариев надо войти в систему.
    Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.

    Copyright © 2010-2023 Русаков Михаил Юрьевич. Все права защищены.

    Источник

    Оцените статью