PHP Категории (Дерево категорий). Самый простой и логичный ЧПУ для PHP Бдительный categories php

И так для начала опишу с чем мы будем работать и что нам понадобится.
Система : PHP 5 и выше, mySQL 4 и выше
Вспомогательные классы : dbsql.class.php (класс для работы с базой данных)
Класс вложенных категорий : classTreeCategory.php (непосредственно основной класс, ниже приведен его листинг и пояснения.

Создаем таблицу в БД, следующей структуры:

Просмотр кода MYSQL

В данной таблице присутствует поле ID — порядковый номер категории, podcat — имеет значение ноль у категорий первого порядка или ID родительской категории, name — название категории.

Пример работы класса, вывод категорий списком с подкатегориями:

Просмотр кода PHP

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 name

Как видно из примера выше, все предельно просто, создаем новый объект $category, устанавливаем с какой таблицей БД работаем: ‘category’, далее получаем из таблицы список всех категорий уже оформленный в виде массива и разложенных в иерархичном порядке, с учетом всех подкатегорий. затем передаем массив в метод outCategory() который формирует для нас готовый HTML код, который остается только вывести в браузер.

Метод outCategory(), как мы видим принимает два параметра @array и @string в первом параметре массив со всеми категориями, а во втором строка содержащая значение option или table , это значени указывает какой тип HTML кода требуется сформировать.
Значение option

Просмотр кода HTML

-категория1 --подкатегория 1 ---подподкатегория 1 -категория 2

Для вставки данного HTML кода в поле select какой либо формы.

Значение table — формирует следующий HTML код:

Просмотр кода HTML

Этот 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 name * */ /** * Дамп таблицы с которой ведется работа * * 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=MyISAM 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]"; endforeach; $str.="[{$item["podcat"]}]"; $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;$icountPodcat;$i++) { $out.="-"; } if($idSel==$sub["id"])$se="selected"; else $se=""; if($type=="option")$this->html.=" {$out} {$sub["name"]} "; 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)"); } } }

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

Буду признателен если в комментариях вы предложите собственные варианты решения данной задачи — организации категорий бесконечного уровня вложенности.

Приветствую всех читателей блога WordPress Inside в 2011 году, поздравляю с наступившими и наступающими праздниками, желаю много здоровья, счастья и радости на следующие 360 дней. Как и обещал в своей статье про планы на будущий 2011 год занимаюсь по чуть-чуть улучшением всех своих основных блогов — обновляю системы, ставлю последние версии плагинов и копаюсь в шаблонах ради оптимизации и исправления ошибок. Работал это крайне сложная, я бы даже сказал очень кропотливая — находишь одну неточность, решаешься ее исправить и перед тобой 5 отдельных проектов, для каждого из которых нужно внести правки. Ну, раз я уже запланировал все это сделать, назад дороги нет, заодно в процессе получаю дополнительный опыт и уже нашел штук 5-6 тем для новых постов в блог:) Сегодня поговорим о категориях и функциях для их отображения.

В одной из прошлых статей блога я публиковал хак который помогает . Данное решение использовалось для функции вывода списка категорий в сайдбаре с помощью функции wp_list_categories. На выходе вы получали записи вроде этой:

Безопасность

Если уж для seo атрибут title имеет хоть какое-то значение, то куда полезнее там было бы разместить просто название категории, а не весь этот ненужных текст. Собственно, указанная выше ссылка на хак помогала решить эту проблему. Но вот ни задача, все это было справедливо (работало) для , которая позволяла предварительно обработать полученный список не выводя его сразу же. Но что делать с другими функциями для вывода категорий? — вот в чем вопрос.

Например, я сегодня совершенно случайно обнаружил, что куча ненужного текста в атрибут title ссылки пишется и при отображении списка категорий для конкретного поста.

Вся проблема заключалась в том, что здесь используется функция the_category , для которой, к сожалению, нельзя задать параметр, чтобы результат ее вызова не отображался сразу. Зато в вордпресс есть еще одна функция get_the_category, которая возвращается массив объектов категорий для конкретного поста.

Функция get_the_category

Синтаксис функции get_the_category достаточно прост:

Программисты знают, что нулевой параметр массива выводит первый элемент, собственно это и объясняет принцип работы данного кода.

Для этого в качестве параметра функции нужно передавать id поста, что и происходит в коде.

Кстати, данную функцию я использую в некоторых сайтах, чтобы выводить название категории поста, но без активной ссылки — так просто дополнительный полезный текст на странице. В таком случае можно применить код:

Ну, и напоследок, немного поразмыслив получился хак для вывода списка категории для поста без использования функции the_category, которую мы успешно заменяем на get_the_category. Если вы хотите добавить код непосредственно в то место шаблона, где выводятся категории, например, файл archive.php, то пишем что-то вроде:

Можно, в принципе разместить код для отображения категорий в файле функций, а потом в файлах шаблона поменять the_category на новую функцию, например, под названием my_thecat(). Конечно, не забудьте предварительно перед заменой добавить соответствующий код в файл функций functions.php:

function my_thecat() { global $post ; foreach ((get_the_category($post -> ID ) ) as $category ) { echo " cat_ID ) . "" title="" . $category -> cat_name . "">" . $category -> cat_name . "; " ; } }

function my_thecat() { global $post; foreach((get_the_category($post->ID)) as $category) { echo "cat_ID)."" title="".$category->cat_name."">".$category->cat_name."; "; } }

Потестировал, все работает. Остается лишь один вопрос — насколько это все полезно и крайне необходимо. Если у вас один блог с постоянным дизайном, который вы хотите сделать самым лучшим, то можно потратить пару минут и внести соответствующие изменения. В случае если у вас таких блогов много, думаю, особой seo выгоды манипуляция с title не принесет в плане, проще купить ссылок в Rotapost на все эти проекты — кстати эксперимент по подъему тИЦ в системе успешно и позитивно завершен, скоро будет отчет об этом.

Вывод категорий кастомных записей

В комментариях подсказывают, что примеры, указанные выше, не работают для кастомных (пользовательских) типов записей. Я с этой задачей не сталкивался, поэтому могу вам лишь посоветовать погуглить решение в англоязычных блогах по ключу wordpress custom post type show category или же воспользоваться подсказкой пользователя Stinker (из комментариев). В месте вывода категорий нужно просто вставить код:

Где categoria_video — это таксономия пользовательской записи (она же кастомная). А теперь более подробно от куда и что. Например у нас есть:

// Тип записи Видео if ( ! function_exists ( "video_cp" ) ) { function video_cp() { $labels = array ( "name" => _x( "Видео" , "Post Type General Name" , "video" ) , "singular_name" => _x( "Видео" , "Post Type Singular Name" , "video" ) , "menu_name" => __( "Видео" , "video" ) , "parent_item_colon" => __( "Родительский:" , "video" ) , "all_items" => __( "Все видеоматериалы" , "video" ) , "view_item" => __( "Просмотреть" , "video" ) , "add_new_item" => __( "Добавить новое видео" , "video" ) , "add_new" => __( "Добавить видео" , "video" ) , "edit_item" => __( "Редактировать видео" , "video" ) , "update_item" => __( "Обновить видео" , "video" ) , "search_items" => __( "Найти видео" , "video" ) , "not_found" => __( "Не найдено" , "video" ) , "not_found_in_trash" => __( "Не найдено в корзине" , "video" ) , ) ; $args = array ( "labels" => $labels , "supports" => array ( "title" , "editor" , "excerpt" , ) , "taxonomies" => array ( "categoria_video" ) , // категория, которую мы создадим ниже (она же таксономия) "public" => true , "menu_position" => 5 , "menu_icon" => "dashicons-id-alt" , ) ; register_post_type( "video" , $args ) ; } add_action( "init" , "video_cp" , 0 ) ; // инициализируем } if ( ! function_exists ( "categoria_video" ) ) { // Категории для вакансий function categoria_video() { $labels = array ( "name" => _x( "Категории Видео" , "Taxonomy General Name" , "categoria_video" ) , "singular_name" => _x( "Категория Видео" , "Taxonomy Singular Name" , "categoria_video" ) , "menu_name" => __( "Категории" , "categoria_video" ) , "all_items" => __( "Категории" , "categoria_video" ) , "parent_item" => __( "Родительская категория Видео" , "categoria_video" ) , "parent_item_colon" => __( "Родительская категория Видео:" , "categoria_video" ) , "new_item_name" => __( "Новая категория" , "categoria_video" ) , "add_new_item" => __( "Добавить новую категорию" , "categoria_video" ) , "edit_item" => __( "Редактировать категорию" , "categoria_video" ) , "update_item" => __( "Обновить категорию" , "categoria_video" ) , "search_items" => __( "Найти" , "categoria_video" ) , "add_or_remove_items" => __( "Добавить или удалить категорию" , "categoria_video" ) , "choose_from_most_used" => __( "Поиск среди популярных" , "categoria_video" ) , "not_found" => __( "Не найдено" , "categoria_video" ) , ) ; $args = array ( "labels" => $labels , "hierarchical" => true , "public" => true , ) ; register_taxonomy( "categoria_video" , array ( "video" ) , $args ) ; } add_action( "init" , "categoria_video" , 0 ) ; // инициализируем }

// Тип записи Видео if (! function_exists("video_cp")) { function video_cp() { $labels = array("name" => _x("Видео", "Post Type General Name", "video"), "singular_name" => _x("Видео", "Post Type Singular Name", "video"), "menu_name" => __("Видео", "video"), "parent_item_colon" => __("Родительский:", "video"), "all_items" => __("Все видеоматериалы", "video"), "view_item" => __("Просмотреть", "video"), "add_new_item" => __("Добавить новое видео", "video"), "add_new" => __("Добавить видео", "video"), "edit_item" => __("Редактировать видео", "video"), "update_item" => __("Обновить видео", "video"), "search_items" => __("Найти видео", "video"), "not_found" => __("Не найдено", "video"), "not_found_in_trash" => __("Не найдено в корзине", "video"),); $args = array("labels" => $labels, "supports" => array("title", "editor", "excerpt",), "taxonomies" => array("categoria_video"), // категория, которую мы создадим ниже (она же таксономия) "public" => true, "menu_position" => 5, "menu_icon" => "dashicons-id-alt",); register_post_type("video", $args); } add_action("init", "video_cp", 0); // инициализируем } if (! function_exists("categoria_video")) { // Категории для вакансий function categoria_video() { $labels = array("name" => _x("Категории Видео", "Taxonomy General Name", "categoria_video"), "singular_name" => _x("Категория Видео", "Taxonomy Singular Name", "categoria_video"), "menu_name" => __("Категории", "categoria_video"), "all_items" => __("Категории", "categoria_video"), "parent_item" => __("Родительская категория Видео", "categoria_video"), "parent_item_colon" => __("Родительская категория Видео:", "categoria_video"), "new_item_name" => __("Новая категория", "categoria_video"), "add_new_item" => __("Добавить новую категорию", "categoria_video"), "edit_item" => __("Редактировать категорию", "categoria_video"), "update_item" => __("Обновить категорию", "categoria_video"), "search_items" => __("Найти", "categoria_video"), "add_or_remove_items" => __("Добавить или удалить категорию", "categoria_video"), "choose_from_most_used" => __("Поиск среди популярных", "categoria_video"), "not_found" => __("Не найдено", "categoria_video"),); $args = array("labels" => $labels, "hierarchical" => true, "public" => true,); register_taxonomy("categoria_video", array("video"), $args); } add_action("init", "categoria_video", 0); // инициализируем }

Спасибо пользователю Stinker за подсказку, возможно, вам она пригодится.

P.S. Постовой. В одном из блогов рунета была найдена замечательная подборка тем wordpress портфолио из 17-ти бесплатных качественных шаблонов.

Category subcategory tree view provides a user-friendly way to list the parent and child categories. The category and their subcategory are easily separated by a tree structure. The categories tree view is always recommended to display an infinite level of categories and subcategories.

In this tutorial, we will show you how to create dynamic category subcategory tree using PHP and MySQL. The recursive category tree is very useful to list n level categories in a dropdown. The example code helps you to build n level category subcategory dropdown in PHP. The dynamic categories data will be retrieved from the MySQL database and listed in a parent-child category tree format.

Create Database Table

To store categories and subcategories, a table needs to be created in the database. The following SQL creates a categories table in the MySQL database.

CREATE TABLE `categories ` (`id` int (11 ) NOT NULL AUTO_INCREMENT, `parent_id` int (11 ) NOT NULL DEFAULT "0" , `name` varchar (100 ) COLLATE utf8_unicode_ci NOT NULL , `created` datetime NOT NULL , `modified` datetime NOT NULL , `status` enum("1" ,"0" ) COLLATE utf8_unicode_ci NOT NULL DEFAULT "1" COMMENT "1:Active, 0:Inactive" , PRIMARY KEY (`id` )) ENGINE= InnoDB DEFAULT CHARSET= utf8 COLLATE= utf8_unicode_ci;

The parent_id column specifies whether the category is parent or child. If parent_id is 0, it will be a parent category. Otherwise, it will be a child category and the ID is the parent of this category.

Database Configuration (dbConfig.php)

The dbConfig.php file is used to connect and select the database. Specify the database host ($dbHost), username ($dbUsername), password ($dbPassword), and name ($dbName) as per your MySQL credentials.

PHP Recursive Function to Generate Parent/Child Tree

The categoryTree() function generates an n level category subcategory tree using PHP. It will create the dropdown options for categories tree.

  • $parent_id – Optional. Specify the parent ID to get the child categories of this parent category.
  • $sub_mark – Optional. Mark that will append at the beginning of the child category name.