Fil d'ariane dynamique en php

Nouveau WRInaute
Bonjour à tous,

Je voudrais créer un fil d'ariane automatique, j'ai donc créer une table dans ma BDD avec les champs suivants :

* id (l'identifiant de la catégorie)
* title (le titre de la catégorie)
* parent (la catégorie "parente" de la catégorie)

La catégorie "de base" (ou catégorie "root") porte l'id 0.
Il peut y avoir autant de catégories que de sous-catégories souhaité.

Par exemple la catégorie d'ID 5 peut être une sous-catégorie de la catégorie 1 qui est elle même sous-catégorie de la catégorie de base (ID 0).

J'aimerais savoir comment créer un fil d'ariane automatique qui s'arreterais à la catégorie 0.
Exemple : Catégorie 0 > Catégorie 1 > Catégorie 5

Merci d'avance
 
WRInaute discret
Il faut créer une table avec un champ ID et un champ PARENT. Le ou les répertoires root ont pour PARENT la valeur NULL ; les autres, l'ID de leur répertoire parent. Au final, on a une véritable arborescence stockés dans une bdd.
Cela se réalise très bien et se met à jour automatiquement en cas de modification par le biais des foreign key : http://en.wikipedia.org/wiki/Foreign_key

Avec MySQL, il te faut utiliser innoDB (largement diffusé).
 
WRInaute accro
j'ai un truc dans le genre qui fait appel a une classe (rubrique) puisque sous mon cms, les rubrique son comme tu l'explique toutes 'attachées' a une rubrique mère et que la mère des filles est celle portant l'id 0.

la structure de la table des rubriques (qui comprend peut être des truc inutiles pour toi) est ainsi :

Code:
CREATE TABLE `rubrique` (
  `id` bigint(20) NOT NULL auto_increment,
  `id_mere` bigint(20) NOT NULL default '0',
  `id_createur` bigint(20) NOT NULL default '1',
  `date_creation` datetime NOT NULL,
  `lib` varchar(100) NOT NULL,
  `url` varchar(100) NOT NULL,
  `description` text NOT NULL,
  `comp_article` tinyint(4) NOT NULL default '1',
  `comp_forum` tinyint(4) NOT NULL default '1',
  `comp_annuaire` tinyint(4) NOT NULL default '1',
  `comp_dico` tinyint(4) NOT NULL default '1',
  PRIMARY KEY  (`id`)
);

`id`-> l'identifiant de la rubrique
`id_mere` -> l'identifiant de la rubrique mére
`id_createur` -> l'identifiant de l'utilisateur qui a créé cette rubrique
`date_creation` -> la date de création de la rubrique
`lib` -> le libellé de la rubrique (exemple : Telecharger / Download)
`url` -> l'url de la rubrique sous la forme : Telecharger-Download/
`description` -> une description textuelle et éventuellement HTML de la rubrique
`comp_article` -> la rubrique est compatible pour recevoir des articles (oui / non)
`comp_forum` -> la rubrique est compatible pour recevoir des sujet de forum (oui / non)
`comp_annuaire` -> la rubrique est compatible pour recevoir des fiches de site type annuaire (oui / non)
`comp_dico` -> la rubrique est compatible pour recevoir des pages de définition (oui / non)

Attention les types ne sont pas optimisés et certains aurait a gagner en étant mieux définis (mais pour l'instant c'est pas le problème)

Pour utiliser cela, j'ai plusieurs bouts de code qui ont différentes utilité dont un pour ton problème :

Code:
	// le fil d'ariane
	if($my_rub->getid_mere()!=0){
		$arbo = " > ".$my_rub->getlien_url();
		$lrub = new rubrique($my_rub->getid_mere());
		while($lrub->getid_mere()!=0){
			$arbo = " > ".$lrub->getlien_url().$arbo;
			$lrub = new rubrique($lrub->getid_mere());
		}
		$arbo = "<a href=\"$domain\" title=\"$short_domain\">Accueil</a>".$arbo;
		echo "     ".$arbo."<br/><br/>\n";
	}
$my_rub l'instance de l'objet rubrique.
$arbo la chaine de caractère contenant le fil d'ariane sous forme html (cliquable)
$domain le NDD utilisé sous la forme -http://truc.machin.com/
$short_domain le NDD utilisé sous la forme truc.machin.com

ce code fait appel a des méthodes de la classe rubrique il faut donc instancier un objet rubrique ($myrub) les méthodes utilisées sont les suivantes :

les accesseurs :
Code:
		/**
		 * getid_mere
		 * <p>getid_mere</p>
		 * 
		 * @name rubrique::getid_mere()
		 * @return 
		 */
		public function getid_mere(){
			return $this->id_mere;
		}

		/**
		 * getlien_url
		 * <p>getlien_url</p>
		 * 
		 * @name rubrique::getlien_url()
		 * @return String
		 */
		public function getlien_url(){
			return $this->lien_url;
		}

( les propriétés membres sont initialisées depuis la base dans le constructeur )
Le constructeur plus la méthode qui me calcul la totalité du path de la rubrique (dans le système de fichier chaque rubrique A incluse dans une rubrique B correspond a un dossier A qui est un sous dossier de B)
En plus des propriétés membres portant les mêmes noms que les champs de la base la classe défini d'autres propriétés qui sont : full_url, lien_url et directory.
La méthode e_mysql_query($x) est une méthode renvoyant un record-set et gérant sa connexion a la base.

Constructeur et méthodes utiles
Code:
		/**
		 * Constructeur de la rubrique. L'objet est lié a des données qui se 
		 * trouvent en base, le constructeur les recupère et met a jour les 
		 * différentes propriétés de l'objet.
		 * <p>Constructeur de la rubrique</p>
		 * 
		 * @name rubrique::__construct()
		 * @in_id représente la clé primaire de l'objet en base.
		 * @return void
		 */
		public function __construct($in_id){
			require($_SERVER['DOCUMENT_ROOT'].'/util/config/config.php');
			$this->url_separateur = $url_separateur;
			$req="SELECT * FROM ${prefix}rubrique WHERE id=$in_id";
			$res = $this->e_mysql_query($req);
			while($record = mysql_fetch_array($res)){
				$this->id = $record[0];
				$this->id_mere = $record[1];
				$this->id_createur = $record[2];
				$this->date_creation = $record[3];
				$this->lib = stripslashes($record[4]);
				$this->url = $record[5];
				$this->description = stripslashes($record[6]);
				$this->comp_article = $record[7];
				$this->comp_forum = $record[8];
				$this->comp_annuaire = $record[9];
				$this->comp_dico = $record[10];
			}
			$this->full_url = $domain.$this->fullpath();
			$this->lien_url = '<a href="'.$this->full_url.'" title="'.$this->lib.'">'.$this->lib.'</a>';
			$this->directory = $_SERVER['DOCUMENT_ROOT'].'/'.$this->fullpath();
			return;
		}

		public function fullpath(){
			include($_SERVER['DOCUMENT_ROOT'].'/util/config/config.php');
			$path = '';
			$req="SELECT id_mere,url FROM ${prefix}rubrique WHERE id=".$this->id;
				
			$res = $this->e_mysql_query($req);
			while($record = @mysql_fetch_array($res)){
				$midm = $record[0];
				$murl = $record[1];
			}
			while ($midm!=0){
				$path = $murl.$path;
				$req="SELECT id_mere,url FROM ${prefix}rubrique WHERE id=".$midm;
				$res = $this->e_mysql_query($req);
				while($record = @mysql_fetch_array($res)){
					$midm = $record[0];
					$murl = $record[1];
				}
			}
			return $path;
		}

$url_separateur est défini dans le fichier de config du CMS (situé ici : $_SERVER['DOCUMENT_ROOT'].'/util/config/config.php d'ou le require du constructeur) et represente le caractère - (moins) ou _ (underscore)
$prefix est utilisé pour préfixé mes tables (le create table donné plus haut n'est pas préfixé)
$midm et $murl sont utilisés par la méthode fullpath() pour evaluer une chaine
$path dans fullpath() represente le path de la rubriqe.

j'ai d'autre joyeuseté qui me permettent de faire des arbos de dossier genre plan de site etc ...
 
Nouveau WRInaute
Merci à tous pour vos réponses.

julienr a dit:
c'est quelle BDD?
C'est une base de données mysql.

kalex, ma table contient déjà les champs que tu me soumet, j'ai actuellement cette structure :

`id` tinyint(4) NOT NULL auto_increment,
`title` text NOT NULL,
`description` mediumtext NOT NULL,
`parent` tinyint(4) NOT NULL,

zeb, merci ça m'a l'air très intéressant (malheureusement je suis plutôt débutant en php :( ) Je vais essayer quand même de voir ce que je peut faire avec toutes tes indications.

Je vous retiens au courant.
A+
 
WRInaute impliqué
ok mysql et sais-tu quelles version ?
En faite je te demande cela car ce que tu décris est typiquement une problématique récursive...
Et le plus efficace à coder c'est de le faire dans une procédure stockée car
comme cela au niveau code php c'est pas plus compliqué qu'un appel de requête...
maintenant vu que c'est mysql faut une version récente pour faire cela facilement
sinon je te donne ce post car c'est une référence :
Recursive Procedure or Function in Mysql
bon courage !
 
Nouveau WRInaute
Merci pour le lien, mais j'ai un peut de mal avec l'anglais...
La version de MySQL est la 5.0.41, est-ce une version assé récente pour une procédure stockée ?
Si oui peut tu me dire ce qu'il faut faire au niveau de la BDD car au niveau des requêtes je comprend le principe est j'en utilisent plusieurs.
Merci
 
Discussions similaires
Haut