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(); — аналогично предыдущему методу, кроме того что данный метод обновляет категорию, её название и уровень вложенности.
Листинг всего класса по работе с категориями и подкатегориями бесконечного уровня вложенности.
table='category'; // запрос на выборку списка категорий, название таблицы
* $category->outCategory($category->getCategory()); // подготовка вывода категорий(запрос массива категорий)
* echo $category->html; // вывод категорий в HTML
*
*/
/**
* Дамп таблицы с которой ведется работа
*
* 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.="";
if($type=='table')$this->html.= <<{$out}
{$sub['name']}


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)');
}
}
}
Весь класс писался в течении часа и разумеется имеет недочеты, но все этот поправимо. Его использование целесообразно в обучающих целях, хотя впрочем немного допилив его, вы сможете встроить его в любую систему и наслаждаться его работой)).
Буду признателен если в комментариях вы предложите собственные варианты решения данной задачи — организации категорий бесконечного уровня вложенности.
Похожие записи
Оставить комментарий
Senior, Architector
предложить оффер
- Исполнитель пропал, почему такое случается и понять с кем работать? спросил (а) Артем
- Можно ли WordPress считать универсальным движком? спросил (а) Андрей
- Что такое самописный скрипт или CMS? спросил (а) Антон
- Как при поиске в linux используя grep, добавить исключения? спросил (а) Алексей
- Как создать публичный ключ в RSA? спросил (а) Сергей
- Интеграция Тинькофф банк Эквайринг на сайт для приема платежей к записи
- Скрипт парсинга форума к записи
- Интеграция по API с страховым маркетплейсом INSSMART к записи
- Интеграция Тинькофф банк Эквайринг на сайт для приема платежей к записи
- Joomla не пускает в админку к записи
- Все что нужно для работы с WSDL к записи
- Интеграция по API с страховым маркетплейсом INSSMART к записи
Archive
- +2023 (2)
- Март 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 (37)
- Декабрь 2016 (3)
- Ноябрь 2016 (3)
- Октябрь 2016 (2)
- Сентябрь 2016 (3)
- Август 2016 (7)
- Июнь 2016 (3)
- Май 2016 (3)
- Апрель 2016 (3)
- Март 2016 (1)
- Февраль 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 (42)
- Декабрь 2012 (2)
- Ноябрь 2012 (3)
- Октябрь 2012 (7)
- Сентябрь 2012 (2)
- Август 2012 (1)
- Июль 2012 (3)
- Июнь 2012 (2)
- Май 2012 (6)
- Апрель 2012 (2)
- Март 2012 (8)
- Февраль 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)
Свежие записи
- Почему на сайте, что-то может «само» сломаться? 16.03.2023
- Как быстро писать статьи под низкочастотные запросы 28.02.2023
- Разработка сайта для Андрея Ковалёва 30.12.2022
- Разработка плагина для WordPress — Аудиогид 12.12.2022
- Оптимизация скорости работы сайта, поиск слабых мест (от CPU до MySQL) 07.12.2022