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

Consultez la formation au référencement naturel Google de WebRankInfo / Ranking Metrics


yazerty
WRInaute accro
WRInaute accro
 
Messages: 1682
Inscription: Dim Juin 19, 2005 19:47

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

Message le Ven Sep 07, 2007 1:43

Bonjour,

J'ai une table mysql avec ceci :

Code: Tout sélectionner
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 :) ?

French Fred
WRInaute impliqué
WRInaute impliqué
 
Messages: 265
Inscription: Jeu Fév 12, 2004 18:19

Message le Ven Sep 07, 2007 7:08

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.


yazerty
WRInaute accro
WRInaute accro
 
Messages: 1682
Inscription: Dim Juin 19, 2005 19:47

Message le Ven Sep 07, 2007 8:31

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: Tout sélectionner
$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 ^^ ?
Dernière édition par yazerty le Ven Sep 07, 2007 14:00, édité 1 fois.


webmasterlamogere
WRInaute accro
WRInaute accro
 
Messages: 1874
Inscription: Dim Déc 17, 2006 21:08

Message le Ven Sep 07, 2007 8:59

avec une fonction du style :

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


avec l'affichage après la recherche des parents.

French Fred
WRInaute impliqué
WRInaute impliqué
 
Messages: 265
Inscription: Jeu Fév 12, 2004 18:19

Message le Ven Sep 07, 2007 9:57

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 ...

hsii04
Nouveau WRInaute
 
Messages: 29
Inscription: Mar Mar 15, 2005 11:53

Message le Ven Sep 07, 2007 10:59

essaie cette fonction :
Code: Tout sélectionner
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


yazerty
WRInaute accro
WRInaute accro
 
Messages: 1682
Inscription: Dim Juin 19, 2005 19:47

Message le Ven Sep 07, 2007 14:18

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 :-/.


webmasterlamogere
WRInaute accro
WRInaute accro
 
Messages: 1874
Inscription: Dim Déc 17, 2006 21:08

Message le Ven Sep 07, 2007 14:24

yazerty a écrit: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.

yann214
WRInaute impliqué
WRInaute impliqué
 
Messages: 366
Inscription: Jeu Nov 17, 2005 8:59

Message le Ven Sep 07, 2007 16:05

Je peux proposer cette fonction (c'est du récursif) :

Code: Tout sélectionner
    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
Dernière édition par yann214 le Ven Sep 07, 2007 16:20, édité 2 fois.


yazerty
WRInaute accro
WRInaute accro
 
Messages: 1682
Inscription: Dim Juin 19, 2005 19:47

Message le Ven Sep 07, 2007 16:09

Ah je commence à entrevoir un peu la logique de la chose je crois.

J'ai donc recodé ceci :

Code: Tout sélectionner
$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 :-/.

French Fred
WRInaute impliqué
WRInaute impliqué
 
Messages: 265
Inscription: Jeu Fév 12, 2004 18:19

Message le Ven Sep 07, 2007 16:17

modifie dans ta requete WHERE category_id=$category_id
par WHERE category_id=$id

:P

French Fred
WRInaute impliqué
WRInaute impliqué
 
Messages: 265
Inscription: Jeu Fév 12, 2004 18:19

Message le Ven Sep 07, 2007 16:31

Code: Tout sélectionner
        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: Tout sélectionner
        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


yazerty
WRInaute accro
WRInaute accro
 
Messages: 1682
Inscription: Dim Juin 19, 2005 19:47

Message le Ven Sep 07, 2007 16:33

Ah vi :P ;).

J'aboutis donc à ceci :

Code: Tout sélectionner
// 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 écrit: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 :) ?

French Fred
WRInaute impliqué
WRInaute impliqué
 
Messages: 265
Inscription: Jeu Fév 12, 2004 18:19

Message le Ven Sep 07, 2007 16:37

Regarde le code que j'ai ajoute juste avant ton post :P


yazerty
WRInaute accro
WRInaute accro
 
Messages: 1682
Inscription: Dim Juin 19, 2005 19:47

Message le Ven Sep 07, 2007 16:52

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()

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

Formation recommandée sur ce thème :

Formation Référencement naturel Google : apprenez une méthode efficace pour optimiser à fond le référencement naturel dans Google de façon durable... Formation animée par Olivier Duffez et Fabien Facériès, experts en référencement naturel.

Tous les détails sur le site Ranking Metrics : programme, prix, dates et lieux, inscription en ligne.

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: dudo, meteo75 et 0 invités