PHP-MySQL : Mettre en place des catégories sur différents niveaux

Publié le

On a toujours besoin de trier ses produits, articles, billet ou autres dans des catégories.

Si on en a beaucoup, on veut pouvoir d?finir plusieurs niveaux de catégories.

Je vais vous montrer ici comment on peut simplement gérer différents niveaux de catégories. Par exemple, on peut avoir :

Auto-Moto
Auto
Berline
4x4
Coupé
Moto
125
250
Immobilier
Location
Achat

On voit ici qu'on peut aller jusqu'à 3 niveaux de profondeur (Berline ou 125 par exemple) mais qu'on a aussi des catégories au 2ème niveau (Location). Avec un nombre fixe de niveaux, c'est assez simple : une table MySQL pour chaque niveau, avec chacun un identifiant vers sa catégorie mère et le tour est joué. Là, nous allons devoir faire autrement.

1) La table MySQL
Pour commencer, voici la structure de la table MySQL que j'utilise :

CREATE TABLE cat (
id_cat int not null auto_increment primary key,
rid_cat int default '0',
nom varchar(50) not null
);

id_cat : identifiant unique de la catégorie.
rid_cat : clé étrangère, qui fait référence à la catégorie mère, s'il y en a une.
nom : le nom de la catégorie.

Avec cette table, n'importe quel élément qui doit être rattaché à une catégorie le sera avec son id_cat, indifférement de son niveau, puisque toutes les catégories sont stockées dans cette même table.

Maintenant que la façon de stockée ces catégories est en place, voyons comment tirer parti de cette structure

2) La récupération des catégories mères
Pour la navigation, il est toujours agréable de mettre en place en haut de la page le cheminement des catégories depuis l'accueil.
Par exemple Accueil > Auto-Moto > Auto quand on se trouve sur la page des autos, avec un lien sur chaque intitulé pour revenir sur la page concernée.

Pour récupérer toutes les catégories mères d'une catégorie donnée, nous allons utiliser une fonction récursive. Les mathophobes, rester avec nous, il n'y a pas de grands rapports avec les suites ou séries mathématiques que vous connaissez. Le rapport vient du fait que cette fonction va faire des appels à elle-même pour avancer dans la hiérarchie. Voici cette fonction PHP :

function recupMere($idCat) {
$data = mysql_fetch_array(mysql_query("SELECT id_cat,rid_cat,nom FROM cat WHERE id_cat='$idCat'"));
$ret = '';
if (!empty($data['rid_cat'])) $ret = recupMere($data['rid_cat']).' > ';
$ret.= $data['nom'];
return $ret;
}

En fait, on continue la recherche de la mère tant que rid_cat n'est pas vide. A chaque nouvelle catégorie rencontrée, on concatène avec > comme séparateur pour arriver au résultat escompté.

3) La récupération des catégories filles
Pour la première fonction, la simplicité venait du fait qu'une catégorie a 0 ou 1 catégorie mère, ce qui permet de créer la chaine simplement. Pour récupérer les filles, c'est un peu plus compliqué selon ce qu'on veut en faire. Voici par exemple une fonction permettant de créer une liste déroulante avec toutes les sous-catégories de la catégorie demandée :

function selFilles($idCat=0, $mere='') {
$ret = '';
$req = mysql_query("SELECT id_cat,nom FROM cat WHERE rid_cat='$idCat'");
while ($row = mysql_fetch_array($req)) {
$ret.= '
$ret.= selFilles($row['id_cat'],$mere.$row['nom'].' > ');
}
return $ret;
}
Le premier paramètre sert à spécifier la catégories à partir de laquelle on veut afficher les sous-catégories. Par défaut il vaut 0, ce qui veut dire qu'on afficherait toutes les catégories de la base. Avec notre exemple, on obtiendrai ceci :
Le second paramètre est utilisé pour conserver le chemin parcourut jusque là. On aurait pu aussi rappeler la première fonction, mais on économise ainsi des requêtes MySQL, autant ne pas s'en priver !

Bien sûr, on peut imaginer des autres applications, pour sortir les catégories dans un fichier XML pour une utilisation dans Flash par exemple.

Vous pouvez télécharger les sources, avec quelques exemples et la base de donnée utilisée dans l'exemple.

Si vous avez d'autres idées ou suggestions pour cet article, n'hésitez pas, les commentaires sont là pour ça.