Aujourd'hui, je vais vous dire comment MySQL créer un arbre hiérarchique.
De tels arbres sont utilisés lors de la construction des catégories d'un site dynamique, par exemple, dans une boutique en ligne ou lors de l'affichage de commentaires sur une publication.
En général, ils sont construits dans la mesure du possible. L'essentiel est de le construire et de l'appliquer correctement.
La chose la plus importante lors de la construction d'un arbre hiérarchique est la structure correcte de la base de données ! Par exemple, considérons la structure de la base de données où sont stockées les catégories du site. Pour un exemple simple, la table aura 3 champs :
- identifiant- clé de catégorie
- id_parent— id de la catégorie parent
- nom- titre de la rubrique
Créons une table en exécutant une requête SQL dans PHPMyAdmin :
CREATE TABLE `categories` (`id` INT NOT NULL AUTO_INCREMENT , `parent_id` INT NOT NULL , `name` VARCHAR(50) NOT NULL , PRIMARY KEY (`id`));
Maintenant, nous devons remplir notre table avec des enregistrements. En conséquence, vous devriez obtenir quelque chose comme ce tableau :
Vous pouvez remplir la table de test avec la requête :
INSERT INTO `categories` (`id`, `parent_id`, `name`) VALUES (1, 0, "Section 1"), (2, 0, "Section 2"), (3, 0, "Section 3" ), (4, 1, "Section 1.1"), (5, 1, "Section 1.2"), (6, 4, "Section 1.1.1"), (7, 2, "Section 2.1"), (8 , 2, « article 2.2 »), (9, 3, « article 3.1 »);
Et maintenant attention ! De plus, logiquement, vous devez effectuer des sélections à partir de la base de données en boucle pour sélectionner chaque catégorie et sa sous-catégorie. MAIS! Eh bien, s'il y a plusieurs catégories dans la base de données, ce n'est pas non plus correct en principe. Et si le site est une boutique en ligne et qu'il comporte une centaine de catégories et le même nombre de sous-catégories ? Alors ennuis ! Un nombre inconnu de requêtes à la base de données ralentira le site ou plantera complètement le serveur mysql.
Vous ne pouvez utiliser qu'une seule requête dans la base de données pour sélectionner toutes les catégories et leurs sous-catégories.
Faisons une demande et formons un tableau pratique pour un travail ultérieur.
//Sélection des données de la base de données $result=mysql_query("SELECT * FROM categories"); //S'il y a des enregistrements dans la base de données, nous formons un tableau if (mysql_num_rows($result) > 0)( $cats = array(); //Dans la boucle, nous formons un tableau de sections, la clé sera le id de la catégorie parente, ainsi qu'un tableau de sections, la clé sera l'id de la catégorie while($cat = mysql_fetch_assoc($result))( $cats_ID[$cat["id"]] = $cat; $cats[ $cat["id_parent"]][$cat["id"]] = $cat; ) )
Sélection de toutes les données d'un tableau catégories et forment un tableau associatif $chats, la clé sera l'identifiant de la catégorie parent.
Nous allons maintenant construire un arbre. Pour la construction, nous utiliserons fonction récursive.
L'arborescence hiérarchique aura la structure suivante :
- Section 1
- Article 1.1
- Article 1.1.1
- Article 1.2
- Article 1.1
- Section 2
- Article 1.1
- Article 1.2
- Section 3
- Article 3.1
Créons une fonction récursive build_tree() . Il construira notre arbre hiérarchique d'absolument n'importe quelle imbrication.
Fonction build_tree($cats,$parent_id,$only_parent = false)( if(is_array($cats) and isset($cats[$parent_id]))( $tree = "
- "; if($only_parent==false)( foreach($cats[$parent_id] as $cat)( $tree .= ""; ) )elseif(is_numeric($only_parent))( $cat = $cats[$parent_id ][$only_parent] ; $arbre .= "
- ".$chat["nom"]." #".$cat["id"] ; $tree .= build_tree($cats,$cat["id"]); $tree .= " "; ) $arbre .= "
La fonction prend un tableau de sections et un identifiant de section. Dans la boucle, on parcourt les sous-catégories et si elles ont plus de sections, alors la fonction est relancée avec de nouveaux paramètres (un nouveau tableau de sections et l'id de la section à construire). C'est ainsi que se forme un arbre de n'importe quelle nidification !
Pour construire un arbre, on écrit dans le code :
echo build_tree($cats,0);
Ainsi, en deux étapes, nous avons créé une arborescence hiérarchique des sections du site et peu importe le nombre de sections !
UPD Si vous avez besoin d'une arborescence de catégories dans ordre inverse connaissant l'identifiant de la catégorie, alors vous devez utiliser la fonction :
Fonction find_parent ($tmp, $cur_id)( if($tmp[$cur_id]["parent_id"]!=0)( return find_parent($tmp,$tmp[$cur_id]["parent_id"]); ) return ( int)$tmp[$cur_id]["id"]; )
Cette fonction prend un tableau de catégories, dont la clé est l'identifiant de la catégorie, et l'identifiant de la catégorie à partir de laquelle remonter.
Pour construire un tel arbre, exécutez la fonction build_tree avec les paramètres suivants :
echo build_tree($cats,0,find_parent($cats_ID,YOUR_CATEGORY_ID));
Avoir des questions? Demandez dans les commentaires
Aujourd'hui, notre objectif est de créer une structure hiérarchique des catégories. Il est important pour nous qu'il soit pratique de stocker des catégories et qu'il soit facile de les afficher là où nous en avons besoin.
Parfois, le simple semble compliqué, c'est pourquoi je vais vous présenter quelques extraits de code qui, je l'espère, vous seront utiles pour implémenter des catégories php sous la forme d'un arbre.
Ainsi, la structure doit être composée de l'identifiant de la catégorie (id), du nom de la catégorie (name) et bien sûr de l'identifiant de la catégorie parent (parent_id). Dans MySQL, cela ressemble à ceci :
CREATE TABLE IF NOT EXISTS `category` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `parent_id` int(11) NOT NULL, PRIMARY KEY (`id`)) MOTEUR =InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0 ;
Structure de table minimale et compréhensible pour stocker les catégories.
INSERT INTO `category` (`id`, `name`, `parent_id`) VALUES (1, "Téléphones et tablettes", "0"), (2, "Voitures", "0"), (3, "Samsung ", "1"), (4, "Apple", "1"), (5, "LG", "1"), (6, "Ford", "2"), (7, "Lexus", "2"), (8, "BMW", "2"), (9, " Galaxy Tab 4", "3"), (10, "Galaxy S6", "3");
Où parent_id=0, cette catégorie n'a pas de catégorie parent.
Tout est clair et simple ici. Passons maintenant à la liste des catégories. Mais pour une sortie correcte de la liste, nous devons d'abord obtenir la liste complète des catégories php, puis seulement, en utilisant la récursivité, former notre arbre. Fonction suivante est d'obtenir cette liste:
Fonction get_cat() ( // interroge la base de données $sql = "SELECT * FROM category"; $result = mysql_query($sql); if(!$result) ( return NULL; ) $arr_cat = array(); if( mysql_num_rows ($résultat) != 0) ( //Pour($i = 0; $i< mysql_num_rows($result);$i++) { $row = mysql_fetch_array($result,MYSQL_ASSOC); //Формируем массив, где ключами являются адишники на родительские категории if(empty($arr_cat[$row["parent_id"]])) { $arr_cat[$row["parent_id"]] = array(); } $arr_cat[$row["parent_id"]] = $row; } //возвращаем массив return $arr_cat; } }
//récupérer le tableau du catalogue $result = get_cat();
Maintenant, nous avons besoin d'une fonction avec récursivité
Function view_cat($arr,$parent_id = 0) ( //Conditions de sortie de la récursivité if(empty($arr[$parent_id])) ( return; ) echo "
- "; // boucle dans le tableau et affiche for($i = 0; $i< count($arr[$parent_id]);$i++) {
echo "
- " .$arr[$parent_id][$i]["name"]."" ; //récursion - vérifie s'il existe des catégories enfants view_cat($arr,$arr[$parent_id][$i]["id "] ); écho " "; ) écho "
Maintenant il ne reste plus qu'à afficher le répertoire à l'écran en utilisant la fonction récursive
View_cat($résultat);
Et en général, c'est tout. De cette façon, nous pouvons obtenir un arbre complet de catégories avec des sous-catégories infinies.
Et donc, pour commencer, je vais décrire avec quoi nous allons travailler et ce dont nous aurons besoin.
Système: PHP 5 et supérieur, mySQL 4 et supérieur
Cours d'assistance: dbsql.class.php (classe base de données)
Classe de catégorie imbriquée: classTreeCategory.php (directement la classe principale, son listing et ses explications sont donnés ci-dessous.
Créez une table dans la base de données avec la structure suivante :
Affichage du code MySQL
Cette table contient un champ IDENTIFIANT- numéro de série de la catégorie, podcast- vaut zéro pour les catégories de premier ordre ou l'identifiant de la catégorie mère, nom- nom de la catégorie.
Un exemple de la classe, affichant les catégories sous forme de liste avec des sous-catégories :
Afficher le code PHP
include("dbsql.class.php") ; include("ClassTreeCategory.php" ) ; $DB = new DB_Engine("mysql" , $settings [ "dbHost" ] , $settings [ "dbUser" ] , $settings [ "dbPass" ] , $settings [ "dbName" ] ) ; // se connecte à la base de données en spécifiant les données d'accès$category = new TreeCategory ($DB ) ; // passe à la catégorie class, l'objet de travail avec la base de données$category -> table = "category" ; // nom de table dans la base de données avec catégories$array = $category -> getCategory() ; // récupère toutes les catégories de la base de données sous la forme d'un tableau à plusieurs niveaux, déjà triées et imbriquées dans l'ordre dont nous avons besoin$category -> outCategory ($array , "option" ) ; // préparation de la sortie des catégories (formant HTML), en passant un tableau avec des catégories echo $category -> html ; // afficher les catégories au format HTML |
Comme vous pouvez le voir sur l'exemple ci-dessus, tout est extrêmement simple, nous créons un nouvel objet $category, définissons avec quelle table de base de données nous travaillons : 'category', puis nous obtenons de la table une liste de toutes les catégories déjà formatées en tableau et décomposés dans un ordre hiérarchique, en tenant compte de toutes les sous-catégories. puis nous passons le tableau à la méthode outCategory(), qui génère pour nous un code HTML prêt à l'emploi, qui ne reste plus qu'à être affiché dans le navigateur.
La méthode outCategory(), comme nous pouvons le voir, prend deux paramètres @array et @string dans le premier paramètre un tableau avec toutes les catégories, et dans le second une chaîne contenant une valeur option ou tableau, cette valeur spécifie le type de code HTML à générer.
Signification option
Afficher le code HTML
Pour insérer le code HTML donné dans le champ de sélection de n'importe quel formulaire.
Signification tableau- génère le code HTML suivant :
Afficher le code HTML
Ce code HTML est pratique à coller dans un tableau qui affiche toutes nos sous-catégories de catégories.
La classe a également les méthodes suivantes :
deleteItem($id);- supprime une catégorie, malgré celles imbriquées
delCatégorie($tableau, $id);— supprime une catégorie avec toutes les sous-catégories imbriquées, $array — un tableau avec toutes les catégories préparées par la méthode $category->getCategory(), $ numéro d'identification catégorie à supprimer
ajouter un item();- cette méthode doit être appelée si vous souhaitez ajouter une catégorie, alors que cette méthode lit les valeurs à partir des données transmises par la méthode POST, c'est-à-dire du tableau $_POST.
$name=$this->PHP_slashes(strip_tags($_POST['name'])); // Nom de catégorie
$podcat=intval($_POST['podcat']); // ID de la catégorie parent, si 0 est spécifié, la catégorie sera à la racine.
mettre à jour l'élément (); - similaire à la méthode précédente, sauf que cette méthode met à jour la catégorie, son nom et son niveau d'imbrication.
Toute la classe a été écrite en une heure et, bien sûr, a des défauts, mais tout cela est réparable. Son utilisation est conseillée à des fins éducatives, même si au fait, après l'avoir un peu fini, vous pouvez l'intégrer dans n'importe quel système et profiter de son travail)).
Je vous serais reconnaissant si, dans les commentaires, vous proposiez vos propres options pour résoudre ce problème - organiser des catégories d'un niveau d'imbrication infini.
Pas un seul site n'est complet sans navigation, ou comme le "menu du site" est également appelé. Ainsi, le menu du site peut être à un niveau et à plusieurs niveaux sous la forme d'un arbre. S'il n'y a pas de difficultés particulières en termes de mise en œuvre avec un menu à un seul niveau, alors lors de la création menu à plusieurs niveaux il faut bien réfléchir.
La chose la plus importante dans cette tâche est de concevoir une base de données pour notre menu à plusieurs niveaux. Créons une table Catégories avec trois champs identifiant, titre, parent Où:
- IDENTIFIANT- identifiant
- Titre- Nom du menu
- parent- Parent de catégorie par défaut 0
Le champ est responsable de la ramification du menu parent Si père = 0, alors cette catégorie est la catégorie parent. Pour ajouter des enfants à la catégorie parent, vous devez spécifier dans le champ parent IDENTIFIANT le parent désiré. Par exemple:
Tableaux avec catégories
Comme on peut le voir dans le tableau, la catégorie mère Voitures il y a deux descendants Mazda Et Honda liés par domaine parent. Et la catégorie motocyclettes deux descendants sont kawasaki Et harley. Dans le même temps, la catégorie Bateaux n'a pas de descendance. J'espère que vous comprenez comment lier les catégories.
Ensuite, nous passons des mots à la pratique. Créons la table Catégories.
CREATE TABLE IF NOT EXISTS `categories` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(255) NOT NULL, `parent` int(10) unsigned NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ; -- -- Vider les données de la table `categories` -- INSERT INTO `categories` (`id`, `title`, `parent`) VALUES (1, "Cars", 0), (2, "Motorcycles", 0) , (3, Mazda, 1), (4, Honda, 1), (5, Kawasaki, 2), (6, Harley, 2), (7, Mazda 3, 3 ), (8, "Mazda 6", 3), (9, "Berline", 7), (10, "Hatchback", 7), (11, "Bateaux", 0), (12, "Liftback", 8), (13, "Crossover", 8), (14, "Blanc", 13), (15, "Rouge", 13), (16, "Noir", 13), (17, "Vert", 13), (18, Mazda CX, 3 ), (19, Mazda MX, 3);L'algorithme de travail se compose des éléments suivants :
Création d'une connexion à la base de données
query("SET NAMES "utf8""); /* * C'est la façon "officielle" orientée objet de faire cela * cependant $connect_error n'a pas fonctionné jusqu'à PHP 5.2.9 et 5.3.0. */ if ($mysqli->connect_error) ( die("La connexion a échoué (" . $mysqli->connect_error . ") " . $mysqli->connect_error); ) /* * Si vous voulez être sûr de la compatibilité avec les versions avant 5.2 .9, * meilleur code comme celui-ci */ if (mysqli_connect_error()) ( die("La connexion a échoué (" . mysqli_connect_errno() . ") " . mysqli_connect_error()); )Écrire une fonction pour obtenir des données de la table Catégories
//Obtenir notre tableau de menu à partir de la base de données sous la forme d'un tableau function getCat($mysqli)( $sql = "SELECT * FROM `categories`"; $res = $mysqli->query($sql); //Créer un tableau où la clé du tableau est l'ID du menu $cat = array(); while($row = $res->fetch_assoc())( $cat[$row["id"]] = $row; ) return $cat; )Nous obtenons un tableau comme celui-ci, où la clé du tableau est l'ID de catégorie.
Fonction Array Tree par Tommy Lacroix
//La fonction pour construire un arbre à partir d'un tableau de Tommy Lacroix function getTree($dataset) ( $tree = array(); foreach ($dataset as $id => &$node) ( //S'il n'y a pas de pièces jointes if (!$node[" parent"])( $tree[$id] = &$node; )else( //S'il y a des enfants, alors boucle dans le tableau $dataset[$node["parent"]][" childs"][$id] = &$ node; ) ) return $tree; )Obtenir un tableau sous la forme d'un arbre
Scénario entier
query("SET NAMES "utf8""); /* * C'est la façon "officielle" orientée objet de faire cela * cependant $connect_error n'a pas fonctionné jusqu'à PHP 5.2.9 et 5.3.0. */ if ($mysqli->connect_error) ( die("La connexion a échoué (" . $mysqli->connect_error . ") " . $mysqli->connect_error); ) /* * Si vous voulez être sûr de la compatibilité avec les versions avant 5.2 .9, * il est préférable d'utiliser ce code */ if (mysqli_connect_error()) ( die("Erreur de connexion (" . mysqli_connect_errno() . ") " . mysqli_connect_error()); ) //Récupérer notre tableau de menu de la base de données en tant que fonction de tableau getCat($mysqli)( $sql = "SELECT * FROM `categories`"; $res = $mysqli->query($sql); //Créer un tableau où la clé du tableau est le menu ID $cat = array(); while ($row = $res->fetch_assoc())( $cat[$row["id"]] = $row; ) return $cat; ) //Fonction pour construire un arbre à partir d'un tableau par la fonction Tommy Lacroix getTree($dataset) ( $tree = array(); foreach ($dataset as $id => &$node) ( //S'il n'y a pas de pièces jointes if (!$node["parent" ])( $tree[$id] = &$node; )else( //S'il y a des enfants, itérer dans le tableau $dataset[$node["parent"]]["childs"][$id] = &$node; ) ) return $tree; ) //Préparez-vous ème tableau avec des données $cat = getCat($mysqli); //Créer un menu arborescent $tree = getTree($cat); //Modèle d'affichage du menu sous forme d'arborescence function tplMenu($category)( $menu = "- ".showCat($category["enfants"]) ."
- ". $cat_menu ."
Le résultat du travail
Menu à plusieurs niveaux en PHP + MySQL pour l'administrateur
Si vous voulez utiliser ce menu dans le panneau d'administration de votre site, vous devez réécrire quelques fonctions tplMenu(), afficherChat().
".$catégorie["titre"].""; )else( $menu = " "; ) if(isset($category["childs"]))( $i = 1; for($j = 0; $j< $i; $j++){ $str .= "→"; } $i++; $menu .= showCat($category["childs"], $str); } return $menu; } /** * Рекурсивно считываем наш шаблон **/ function showCat($data, $str){ $string = ""; $str = $str; foreach($data as $item){ $string .= tplMenu($item, $str); } return $string; } //Получаем HTML разметку $cat_menu = showCat($tree, ""); //Выводим на экран echo ""; ?>
Le résultat du travail
Sélectionnez Voitures → Mazda →→ Mazda 3 →→→ Sedan →→→ Hatchback →→ Mazda 6 →→→ Liftback →→→ Crossover →→→→ Blanc →→→→ Rouge →→→→ Noir →→→→ Vert →→ Mazda CX →→ Mazda MX → Motos Honda → Kawasaki → Bateaux HarleyLa tâche suivante consiste à créer des catégories d'imbrication infinie à l'aide de PHP. Après avoir escaladé plusieurs sites, j'ai trouvé de nombreuses solutions, mais toutes ne sont pas disponibles pour ma compréhension, car. le niveau de programmation y est plus élevé que le mien. Par conséquent, j'ai trouvé la solution la plus simple, peut-être pas la plus élégante, mais qui fonctionne.
D'abord, voyons ce que j'ai dans la base de données
- id - identifiant de notre catégorie
- catégorie — nom de la catégorie
- category_id - ID de la catégorie parent. Il était possible d'appeler parent_id, mais cela m'est plus familier
- lvl — niveau d'imbrication de la catégorie. Nécessaire pour former
- Tout ce qui est barbouillé ne vous est d'aucune utilité, car il y a des informations qui sont nécessaires pour moi personnellement, et pour que vous ne soyez pas induit en erreur - j'ai effacé ces informations inutiles.
Affichage des catégories dans
echo " "; ?>Il n'y a rien de spécial à dire ici, si vous avez des questions, alors écrivez dans les commentaires, et pour ceux qui ne se soucient pas vraiment de ce qui est écrit ici, je vous suggère de voir immédiatement le résultat
Si vous ne comprenez pas, alors nous avons juste besoin du champ lvl dans la base de données afin de savoir combien de "-" mettre avant le nom des catégories. Bien sûr, il existe une méthode plus raffinée sans lvl, mais sur ce moment Je n'ai qu'une seule solution. Comme il change, je mettrai à jour l'article.
Affichage des catégories dans
Et voici une autre solution pour vous, lorsque vous avez besoin de l'afficher non pas dans un formulaire, mais dans une liste.
$out; function foo($category_id){ global $out; $res = mysql_query("SELECT * FROM category WHERE category_id = $category_id"); $out .= "
- "; while($rows = mysql_fetch_assoc($res))( $out .= "
- ".$lignes["catégorie"]." "; foo($lignes["id"]); ) $out .= "
Ici on n'a plus besoin de lvl, donc il y a moins de code. Et ci-dessous le résultat