Créer un Fil d'ariane dynamique (php/mysql)

WRInaute passionné
Bonjour,

J'ai une table mysql avec ceci :

Code:
cat_id - name - parent
1 - Catégorie 1 - 0
2 - Catégorie 2 - 5
3 - Catégorie 3 - 2
4 - Catégorie 4 - 3
5 - Catégorie 5 - 3
...

Il s'agit d'un système de catégorie à plusieurs niveaux. Une catégorie peut en contenir une autre (ceci à l'infini). Si je suis dans la catégorie 5 le fil d'ariane peut ainsi donner :

Index > Catégorie 3 > Catégorie 5 >Catégorie 2

Le "parent" est la clé de la chose, il permet de savoir à quelle catégorie appartient la catégorie (ci-dessus j'ai volontairement fait un exemple un peu tordu pour tenter de l'illustrer).

Je souhaite donc faire un fil d'ariane. J'ai cherché avec mon ami Google, mais je n'ai rien trouvé de probant en terme de code php lié à une base de données MySQL. La plupart des pages que j'ai consultées explique comment faire en javascript ou comment les présenter en CSS.

Pourriez-vous m'aider à réaliser ce petit fil d'ariane s'il vous plait :) ?
 
WRInaute discret
C'est purement algorithmique.
Il te faut realiser une boucle recursive.
Et dans chaque boucle tu devras executer une requete pour recuperer le parent du noeud courant.

Voici la requete que tu devras utiliser.
SELECT cat_id FROM table WHERE parent=XXX

Ta boucle devra s'arreter lorsque le parent sera egal a 0

Sinon fait une recherche sur les boucles recursives.
 
WRInaute passionné
Merci pour cette piste French Fred ! Je pensais qu'il fallait sélectionner toute la table, l'organiser en tableau et trier le tout ensuite. Ca parait plus simple comme tu le dit :) !

J'ai donc fais ceci :

Code:
$category_id = $db_data['category_id'];
while (($sql = "SELECT parent_num, category FROM categories WHERE category_id=$category_id") &&  ($category_id!='0')) {
$req = mysql_query($sql);
$db_data = mysql_fetch_assoc($req);
$category = french($db_data['category']);
echo "<a href=\"c-$category_id.html\">$category</a>";
$category_id = $db_data['parent_num'];
}

Le problème c'est que ça m'affiche les choses dans le désordre : la catégorie affichée la plus à gauche est l'enfant et celle de droite le parent. Ca devrait bien sûr être le contraire.

Y aurait-il une astuce de derrière les fagots pour rebidouiller tout ça dans le bon sens de la marche ^^ ?
 
WRInaute passionné
avec une fonction du style :

Code:
function affiche_cat($id) {
  select...
  if ($parent_num!='0') {
    affiche_cat($parent_num);
    echo ...
  }
}

avec l'affichage après la recherche des parents.
 
WRInaute discret
webmasterlamogere a raison.

Il te faut realiser une function qui va interroger la base.
Cette fonction realiser une boucle recursive.
elle s'appelle elle meme tant qu'une condition n'est pas remplie.
En l'occurence, tu n'attends pas la categorie dite "root"

Ensuite imprimer dans la fonction ou en dehors, c'est un choix a faire.

Je prefere tout mettre dans un tableau que j'inverse via une function php qui est faite pour cela.

Enfin tu boucles sur ce dernier qui est dans l'ordre Root->enfant->enfant 1 de enfant -> enfant 2 de enfant 1 ...
 
Nouveau WRInaute
essaie cette fonction :
Code:
function GetFil($CategorieID)
{
	$r = GetCategorie($CategorieID);

	$lien = "";
	if($r["CategorieParenteID"] == 0)
		$lien .= " &raquo; <a href=\"".HTTP_HOST.$r["URL"]."\">".$r["Categorie"]."</a>";
	else
		$lien .= GetFil($r["CategorieParenteID"])." &raquo; <a href=\"".HTTP_HOST.$r["URL"]."\">".$r["Categorie"]."</a>";
	
	return $lien;
}

GetCategorie est une fonction où tu va chercher les infos de la categorie en question
 
WRInaute passionné
Merci à vous trois pour vos réponses :).

Par contre je ne comprends pas du tout le principe, la logique, comment organiser ça dans mon cas précis (j'ai un niveau relativement amateur en php/mysql).

Je ne comprends pas où est la boucle dans la structure de code proposée par webmasterlamogere. Pourquoi écrire une fonction alors que ce code ne me servira que dans un seul fichier php de tout mon site (je n'ai pas précisé désolé :-/ ) :- ?

Merci pour votre aide en tout cas !

ps : j'ai trouvé ceci mais cela tourne vite à la démonstration de force entre 2 méthodes :-/.
 
WRInaute passionné
yazerty a dit:
Je ne comprends pas où est la boucle dans la structure de code proposée par webmasterlamogere. Pourquoi écrire une fonction alors que ce code ne me servira que dans un seul fichier php de tout mon site (je n'ai pas précisé désolé :-/ ) :- ?
La fonction est récursive : elle s’appelle elle même pour remonter ta hiérarchie. On commence par rechercher le parent avant d’afficher l’élément courant. On s’arrête quand il n’y a plus de parent.
 
WRInaute occasionnel
Je peux proposer cette fonction (c'est du récursif) :

Code:
    function get_categorie_byidparent($cat_id, $parent){
    global $connection;
    $query = "SELECT *
              FROM categorie
              WHERE CAT_ID = '$cat_id'
              AND PARENT = '$parent'";
    $result = $connection->exec_query($query);
    return $connection->get_next_record($result);
  }


function calc_fil_ariane($cat_id, $ref_cat){
    $fil_ariane = '';
    if ($cattmp = get_categorie_byid($cat_id))
      if ($cattmp->PARENT!=0)
        if ($cat_id == $ref_cat)
         $fil_ariane = calc_fil_ariane($cattmp->PARENT, $ref_cat).'<a href="" title="Filtrer sur cette catégorie">'.stripslashes($cattmp->NAME).'</a>';
        else
          $fil_ariane = calc_fil_ariane($cattmp->PARENT, $ref_cat).'<a href="" title="Filtrer sur cette catégorie">'.stripslashes($cattmp->NAME).'</a> &raquo; ';
      else
          $fil_ariane = '<a href="" title="Filtrer sur cette catégorie">'.stripslashes($cattmp->NAME).'</a> &raquo; ';
    return $fil_ariane;
  }

$ref_cat est la catégorie fille de laquelle on part pour remonter en haut de l'arborescence.
Ce code à pour effet de présenter les catégories comme cela :
cat1 >> cat2 >> cat3
 
WRInaute passionné
Ah je commence à entrevoir un peu la logique de la chose je crois.

J'ai donc recodé ceci :

Code:
$category_id = $db_data['category_id'];
echo $category_id; // affiche bien l'id de la catégorie en cours (20)
function affiche_cat($id) {
$sql = "SELECT parent_num, category FROM categories WHERE category_id=$category_id";
$req = mysql_query($sql) or die(mysql_error());
$db_data = mysql_fetch_assoc($req);
$parent_num = $db_data['parent_num']; 
  if ($parent_num!='0') {
    affiche_cat($parent_num);
    echo $db_data['category'];
  }
}
affiche_cat($category_id);

Mais il me sort une erreur SQL :

20You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

Si j'enlève mon mysql_error() il me lance une boucle infinie avec ce message d'erreur (répété à l'infini) :

Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in

Je ne vois pas ce qui bug dans mon SELECT là :- ?

Et si je place un echo $parent_num; avant le "if {}" cela n'affiche pas le numéro du parent_num :-/.
 
WRInaute discret
Code:
        function getTopParent($pi_current, &$pa_data)
        {

            // sql + query
            $sSql = 'SELECT  parent_num, category FROM categories WHERE id='.$pi_current;
            $req = mysql_query($sSql) or die(mysql_error());

            if (mysql_affected_rows($req)>0)
            {
                $aData = mysql_fetch_assoc($req); 
                $pa_data[] = $aData;

                getTopParent($aData['parent_num'], $pa_data);
            }
        }


        // Appel de la function
        getTopParent($db_data['category_id'], $pa_data) ;
        
        // Reverse l'ordre des resultats pour avoir en premier le root
        $aFinalData = array_reverse($pa_data) ;

$aFinalData sera de la forme:

Code:
        Array
        (
            [0] => Array
                (
                    [parent_num] => 1
                    [category] => categorie Root
                )
            [1] => Array
                (
                    [parent_num] => 2
                    [category] => Enfant de Root
                )
            [2] => Array
                (
                    [parent_num] => 3
                    [category] => Enfant de "Enfant de Root"
                )
        )

Bon je n'ai pas teste mais ca devrait fonctionner approximativement comme cela
 
WRInaute passionné
Ah vi :p ;).

J'aboutis donc à ceci :

Code:
// Fil d'Ariane (c'était Alphonse le fils d'Ariane non ?)
$category_id = $db_data['category_id'];
echo $category_id; // affiche bien l'id de la catégorie en cours

function affiche_cat($id) {
$sql = "SELECT parent_num, category FROM categories WHERE category_id=$id";
$req = mysql_query($sql);
$db_data = mysql_fetch_assoc($req);
$parent_num = $db_data['parent_num'];
$category = $db_data['category'];
echo "<strong>$id $category - </strong>";
if ($parent_num!='0') {
   affiche_cat($parent_num);
}
}
affiche_cat($category_id);
(il faut que je place mon echo "" avant le if {} sinon ça n'affiche pas la dernière catégorie (ou plutôt la première, c'est à dire celle la plus proche de 0).

Cela affiche bien mes catégories, avec le bon numéro d'id mais par contre elles sont toujours affichées dans le sens inverse.

Cela donne actuellement avec la fonction ci-dessus :

20 Catégorie inférieure - 16 Catégorie supérieure -

J'imagine qu'il faut maintenant que j'attaque :

French Fred a dit:
Ensuite imprimer dans la fonction ou en dehors, c'est un choix a faire.

Je prefere tout mettre dans un tableau que j'inverse via une function php qui est faite pour cela.

Mais quelle est donc cette fonction magique qui permet d'inverser ces ptites choses :) ?
 
WRInaute passionné
lol décidément ;).

J'ai essayé ton code entier (en remplaçant id par category_id dans le SELECT) car il me parait plus propre que le mien, mais cela m'a retourné ces erreurs :

Warning: mysql_affected_rows(): supplied resource is not a valid MySQL-Link resource

Warning: array_reverse() [function.array-reverse]: The argument should be an array

Warning: Invalid argument supplied for foreach()
 
WRInaute passionné
Muuh c'est mieux, ça fait déjà une erreur en moins :) mais le code bloque toujours sur le tableau apparemment (même erreurs que précédemment) :

Warning: array_reverse() [function.array-reverse]: The argument should be an array

Warning: Invalid argument supplied for foreach()

J'imagine que la seconde erreur découle de la première.

J'ai cherché sur Google pour tenter de voir comment marchent les tableaux / array en php, mais je ne comprends pas pourquoi ça ne marche pas là :eek: ...

EDIT : problème résolu :) ! Merci à vous tous pour votre aide :).
 
Discussions similaires
Haut