PHP: Категории бесконечного уровня вложенности.
Приветствую вас мои дорогие читатели, сегодня я хочу поделиться с вами моими небольшими наработками по созданию скрипта(класса) для работы с категориями и подкатегориями бесконечного уровня вложенности. Необходимость применения сие функционала может потребоваться где угодно, например в организации категорий новостей, статей, товаров в интернет магазине или же вообще пользовательских комментариев с ответами, также вложенными друг в друга.
И так для начала опишу с чем мы будем работать и что нам понадобится.
Система: PHP 5 и выше, mySQL 4 и выше
Вспомогательные классы: dbsql.class.php (класс для работы с базой данных)
Класс вложенных категорий: classTreeCategory.php (непосредственно основной класс, ниже приведен его листинг и пояснения.
Создаем таблицу в БД, следующей структуры:
DROP TABLE IF EXISTS `category`; CREATE TABLE `category` ( `id` int(11) NOT NULL auto_increment, `podcat` int(11) NOT NULL, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`), KEY `id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
В данной таблице присутствует поле ID — порядковый номер категории, podcat — имеет значение ноль у категорий первого порядка или ID родительской категории, name — название категории.
Пример работы класса, вывод категорий списком с подкатегориями:
include('dbsql.class.php'); include('classTreeCategory.php'); $DB=new DB_Engine('mysql', $settings['dbHost'], $settings['dbUser'], $settings['dbPass'], $settings['dbName']); // подключаемся к БД, с указанием данных доступа $category = new TreeCategory ($DB); // передаем в класс категорий, объект работы с БД $category->table='category'; // название таблицы в БД с категорийми $array=$category->getCategory(); // получаем все категории из БД в виде многоуровневого массива, отсортированные и вложенные уже в нужном нам порядке $category->outCategory($array, 'option'); // подготовка вывода категорий (формируем HTML), передаем массив с категориями echo $category->html; // вывод категорий в виде HTML <option value="id">name</option> |
Как видно из примера выше, все предельно просто, создаем новый объект $category, устанавливаем с какой таблицей БД работаем: ‘category’, далее получаем из таблицы список всех категорий уже оформленный в виде массива и разложенных в иерархичном порядке, с учетом всех подкатегорий. затем передаем массив в метод outCategory() который формирует для нас готовый HTML код, который остается только вывести в браузер.
Метод outCategory(), как мы видим принимает два параметра @array и @string в первом параметре массив со всеми категориями, а во втором строка содержащая значение option или table, это значени указывает какой тип HTML кода требуется сформировать.
Значение option — формирует следующий HTML код:
<option value="1">-категория1</option> <option value="2">--подкатегория 1</option> <option value="3">---подподкатегория 1</option> <option value="4">-категория 2</option> |
Для вставки данного HTML кода в поле select какой либо формы.
Значение table— формирует следующий HTML код:
<tr><td>-категория1</td><td>кнопки ред и удл</td></tr> <tr><td>--подкатегория1</td><td>кнопки ред и удл</td></tr> <tr><td>---подподкатегория1</td><td>кнопки ред и удл</td></tr> <tr><td>-категория2</td><td>кнопки ред и удл</td></tr> |
Этот HTML код удобен для вставки в таблицу которая отображает все наши категории подкатегории.
Класс имеет также следующие методы:
deleteItem($id); — удаляет одну категорию, не смотря на вложенные
delCategory($array, $id); — удаляет категорию со всеми вложенными подкатегориями, $array — массив со всеми категориями подготовленный методом $category->getCategory(), $id- номер удаляемой категории
addItem(); — данный метод следует вызывать если вы хотите добавить категорию, при этом этот метод считывает значения из данных переданных методом POST, т.е. из массива $_POST.
$name=$this->PHP_slashes(strip_tags($_POST[‘name’])); // имя категории
$podcat=intval($_POST[‘podcat’]); // ID родительской категории, если указан 0 категория будет в корне.
updateItem(); — аналогично предыдущему методу, кроме того что данный метод обновляет категорию, её название и уровень вложенности.
Листинг всего класса по работе с категориями и подкатегориями бесконечного уровня вложенности.
<?php /** * * CMS osRealty 2.1.x * Autor: Roman Chernyshov * E-mail: support@osRealty.ru * URL: www.osRealty.ru * */ /** * * Пример использования * * $category = new TreeCategory ($DB); // передаем в класс интерфес работы с БД * $category->table='category'; // запрос на выборку списка категорий, название таблицы * $category->outCategory($category->getCategory()); // подготовка вывода категорий(запрос массива категорий) * echo $category->html; // вывод категорий в HTML <option value="id">name</option> * */ /** * Дамп таблицы с которой ведется работа * * DROP TABLE IF EXISTS `category`; * CREATE TABLE `category` ( * `id` int(11) NOT NULL auto_increment, * `podcat` int(11) NOT NULL, * `name` varchar(255) NOT NULL, * PRIMARY KEY (`id`), * KEY `id` (`id`) * ) ENGINE=InnoDB DEFAULT CHARSET=utf8; * */ class TreeCategory { /** * Строка запроса в БД */ var $table; /** * Интерфейс работы с БД */ var $DB; /** * Массив категорий с вложенными подкатегориями */ var $arrayCat; /** * Авто-подстчет кол-ва прочерков перед названием категории при выводе */ var $countPodcat; /** * HTML код для вывода категорий с подкатегориями */ var $html; /** * Получаем интерфейс для работы с БД и кладем его в локальные переменную */ function __construct($DB) { $this->DB=$DB; $this->component=$_GET['component']; } /** * Получает список категорий, сортирует и помещает в массив с вложенными массивами и т.д. * @return array category */ function getCategory () { $all = $this->DB->getAll("SELECT * FROM `{$this->table}` ORDER BY `id` ASC"); $path = array(); if(count($all)>0) { foreach($all as $item): if($item['podcat']==0)$sort[$item['id']]=$item; if($item['podcat']>0) { if(isset($path[$item['podcat']])) { $str='$sort'; foreach($path[$item['podcat']] as $pitem): $rep=$item['podcat']; $str.="[$pitem][sub]"; endforeach; $str.="[{$item['podcat']}][sub]"; $str.="[{$item['id']}]"; $str.='=$item;'; eval($str); foreach($path[$item['podcat']] as $pitem): $path[$item['id']][]=$pitem; endforeach; $path[$item['id']][]=$item['podcat']; } else { $sort[$item['podcat']]['sub'][$item['id']]=$item; $path[$item['id']][]=$item['podcat']; } } endforeach; } $this->arrayCat=$sort; return $this->arrayCat; } /** * Печатает категории, помещает готовый HTML в $this->html * @param array Массив с категориями и вложенными подкатегориями * @param string Тип генерируемого HTML кода для вывода, option или table */ function outCategory(&$arrayCat, $type='option', $idSel=0) { foreach($arrayCat as $sub) { $this->countPodcat++; $this->outItem($sub, $type); if(!empty($sub['sub']))$this->outCategory($sub['sub'], $type, $idSel); $this->countPodcat--; } } /** * Вспомогательный метод подготовки HTML кода * @param array Массив с категорией * @param string Тип генерируемого HTML кода для вывода, option или table */ function outItem($sub, $type='option', $idSel=0) { for($i=0;$i<=$this->countPodcat;$i++) { $out.='-'; } if($idSel==$sub['id'])$se='selected'; else $se=''; if($type=='option')$this->html.="<option value=\"{$sub['id']}\" {$se}>{$out} {$sub['name']}</option>"; if($type=='table')$this->html.= <<<HTML <tr><td class="name" width="450">{$out} <img src="images/index.png" width="16" height="16" border="0" alt="{$sub['name']}" /> {$sub['name']}</td> <td align="center"><a href="?component={$this->component}§ion=edit&id={$sub['id']}"> <img src="images/user_edit.png" alt="edit" title="edit" border="0" /></a></td> <td align="center"><a href="?component={$this->component}§ion=delete&id={$sub['id']}" class="ask"> <img src="images/trash.png" alt="del" title="del" border="0" /></a></td></tr> HTML; } function delCategory(&$a_tree,&$id=0) { foreach($a_tree as $sub) { if($sub['id']<>$id and isset($sub['sub']))$this->delCategory($sub['sub'],$id); if($sub['id']==$id) { $sql="DELETE FROM {$this->table} WHERE id = '$id' LIMIT 1"; $this->DB->execute($sql); if (isset($sub['sub'])) $this->delCategory_process($sub['sub']); } } } function delCategory_process(&$a_tree) { foreach($a_tree as $sub) { $sql="DELETE FROM {$this->table} WHERE id = '{$sub['id']}' LIMIT 1"; $this->DB->execute($sql); if(isset($sub['sub']))$this->delCategory_process($sub['sub']); } } function updateItem() { $name=$this->PHP_slashes(strip_tags($_POST['name'])); $podcat=intval($_POST['podcat']); $id=intval($_POST['id']); $sql="UPDATE `{$this->table}` SET `name` = '{$name}',`podcat` = '{$podcat}' WHERE `id`='{$id}' LIMIT 1; "; $this->DB->execute($sql); } function addItem() { $name=$this->PHP_slashes(strip_tags($_POST['name'])); $podcat=intval($_POST['podcat']); $id=intval($_POST['id']); $sql="INSERT INTO `{$this->table}` (`id`,`podcat`,`name`) VALUES ('', '$podcat', '$name');"; $this->DB->execute($sql); } function deleteItem($id) { $id=intval($id); $sql="DELETE FROM `{$this->table}` WHERE `id` = '{$id}' LIMIT 1"; $DB->execute($sql); header("Location: ?component={$this->component}"); } function PHP_slashes($string,$type='add') { if ($type == 'add') { if (get_magic_quotes_gpc()) { return $string; } else { if (function_exists('addslashes')) { return addslashes($string); } else { return mysql_real_escape_string($string); } } } else if ($type == 'strip') { return stripslashes($string); } else { die('error in PHP_slashes (mixed,add | strip)'); } } } |
Весь класс писался в течении часа и разумеется имеет недочеты, но все этот поправимо. Его использование целесообразно в обучающих целях, хотя впрочем немного допилив его, вы сможете встроить его в любую систему и наслаждаться его работой)).
Буду признателен если в комментариях вы предложите собственные варианты решения данной задачи — организации категорий бесконечного уровня вложенности.
Похожие записи
Оставить комментарий
Full Stack
Senior, Architect
предложить оффер
- jQuery: как получить значение атрибута?
- PHP работа с изображением, класс SimpleImage
- Интеграция с API ОСАГО сайта sravni.ru
- Комментарии на PHP, Ajax, mySQL
- PHP: Категории бесконечного уровня вложенности.
- Nginx редирект на другой сервис с сохранением URL спросил (а) Сергей
- Исполнитель пропал, почему такое случается и понять с кем работать? спросил (а) Артем
- Можно ли WordPress считать универсальным движком? спросил (а) Андрей
- Что такое самописный скрипт или CMS? спросил (а) Антон
- Как при поиске в linux используя grep, добавить исключения? спросил (а) Алексей
- Консольный скрипт(JavaScript) для автоматических заказов на OZON к записи
- Консольный скрипт(JavaScript) для автоматических заказов на OZON к записи
- Как создать Telegram-бота с авторизацией через сайт к записи
- PHP скрипт: каталог закладок на сайты к записи
- Валидация на PHP к записи
- Сколько зарабатывают в бизнесе на совместных покупках к записи
- Сколько зарабатывают в бизнесе на совместных покупках к записи
Archive
- +2024 (25)
- Ноябрь 2024 (10)
- Октябрь 2024 (8)
- Сентябрь 2024 (1)
- Август 2024 (5)
- Май 2024 (1)
- +2023 (27)
- Ноябрь 2023 (1)
- Октябрь 2023 (13)
- Сентябрь 2023 (10)
- Апрель 2023 (1)
- Март 2023 (1)
- Февраль 2023 (1)
- +2022 (21)
- Декабрь 2022 (11)
- Ноябрь 2022 (1)
- Май 2022 (2)
- Апрель 2022 (2)
- Март 2022 (3)
- Февраль 2022 (1)
- Январь 2022 (1)
- +2021 (17)
- Декабрь 2021 (5)
- Ноябрь 2021 (2)
- Июль 2021 (1)
- Июнь 2021 (2)
- Май 2021 (5)
- Апрель 2021 (1)
- Март 2021 (1)
- +2020 (20)
- Декабрь 2020 (6)
- Сентябрь 2020 (2)
- Август 2020 (1)
- Июль 2020 (2)
- Май 2020 (2)
- Апрель 2020 (2)
- Март 2020 (2)
- Февраль 2020 (1)
- Январь 2020 (2)
- +2019 (18)
- Декабрь 2019 (3)
- Ноябрь 2019 (2)
- Октябрь 2019 (2)
- Сентябрь 2019 (1)
- Август 2019 (2)
- Июль 2019 (1)
- Июнь 2019 (1)
- Апрель 2019 (2)
- Март 2019 (1)
- Февраль 2019 (3)
- +2018 (44)
- Декабрь 2018 (4)
- Ноябрь 2018 (7)
- Октябрь 2018 (8)
- Сентябрь 2018 (1)
- Август 2018 (4)
- Июль 2018 (5)
- Май 2018 (3)
- Апрель 2018 (7)
- Март 2018 (1)
- Февраль 2018 (2)
- Январь 2018 (2)
- +2017 (19)
- Декабрь 2017 (2)
- Ноябрь 2017 (1)
- Октябрь 2017 (1)
- Сентябрь 2017 (2)
- Июль 2017 (1)
- Июнь 2017 (1)
- Май 2017 (2)
- Апрель 2017 (3)
- Март 2017 (2)
- Февраль 2017 (1)
- Январь 2017 (3)
- +2016 (36)
- Декабрь 2016 (3)
- Ноябрь 2016 (3)
- Октябрь 2016 (2)
- Сентябрь 2016 (3)
- Август 2016 (7)
- Июнь 2016 (3)
- Май 2016 (3)
- Апрель 2016 (3)
- Февраль 2016 (1)
- Январь 2016 (8)
- +2015 (36)
- Ноябрь 2015 (5)
- Октябрь 2015 (4)
- Сентябрь 2015 (1)
- Август 2015 (8)
- Июнь 2015 (1)
- Май 2015 (4)
- Апрель 2015 (8)
- Март 2015 (3)
- Февраль 2015 (2)
- +2014 (26)
- Ноябрь 2014 (2)
- Октябрь 2014 (5)
- Сентябрь 2014 (6)
- Июль 2014 (1)
- Июнь 2014 (2)
- Май 2014 (3)
- Апрель 2014 (6)
- Февраль 2014 (1)
- +2013 (27)
- Декабрь 2013 (2)
- Ноябрь 2013 (1)
- Октябрь 2013 (1)
- Август 2013 (1)
- Июль 2013 (3)
- Июнь 2013 (10)
- Май 2013 (1)
- Апрель 2013 (2)
- Февраль 2013 (3)
- Январь 2013 (3)
- +2012 (41)
- Декабрь 2012 (2)
- Ноябрь 2012 (3)
- Октябрь 2012 (7)
- Сентябрь 2012 (2)
- Август 2012 (1)
- Июль 2012 (3)
- Июнь 2012 (2)
- Май 2012 (6)
- Апрель 2012 (2)
- Март 2012 (7)
- Февраль 2012 (5)
- Январь 2012 (1)
- +2011 (57)
- Декабрь 2011 (6)
- Ноябрь 2011 (2)
- Октябрь 2011 (3)
- Сентябрь 2011 (5)
- Август 2011 (4)
- Июль 2011 (3)
- Июнь 2011 (3)
- Май 2011 (3)
- Апрель 2011 (4)
- Март 2011 (10)
- Февраль 2011 (5)
- Январь 2011 (9)
- +2010 (43)
- Декабрь 2010 (7)
- Ноябрь 2010 (21)
- Октябрь 2010 (14)
- Сентябрь 2010 (1)
Свежие записи
- Интеграция платежной системы MoonPay на сайт по API 10.11.2024
- Парсер товаров с Taobao 08.11.2024
- Упаковка и минификация кода JavaScript онлайн 07.11.2024
- Как эффективно анализировать логи при DDOS атаке 07.11.2024
- Бот для автоматических заказов на OZON (плагин для Chrome) 07.11.2024