Problême de concept - Comment gerer des catégories ?

Problême de concept - Comment gerer des catégories ? - PHP - Programmation

Marsh Posté le 12-01-2004 à 09:20:15    

Bonjour,
Je travaille sur un site de vente de produits. J'arrive sur un problême de développement que je n'avais jamais vu et auquel je ne trouve pas de solution, de maniére adapté.
Il s'agit de gerer des categories et des sous catégories. Comment stocker ca dans la base ? Une catégorie peut avoir un nombre indeterminé de sous catégorie. Une sous catégorie peut contenir d'autres sous catégorie. Je ne vois qu'un moyen. Tout stoquer dans la meme table et faire des espêces d'appels récursif sur cette même table. Est ce possible ? Arriverez vous à me comprendre ?

Reply

Marsh Posté le 12-01-2004 à 09:20:15   

Reply

Marsh Posté le 12-01-2004 à 09:26:49    

les relations récursives existent et à mon avis c'est la seule solution à ton problème :)

Reply

Marsh Posté le 12-01-2004 à 09:57:19    

+1
 
une table avec :
 
id_cat
id_parent_cat
name
 
tu vois le genre

Reply

Marsh Posté le 12-01-2004 à 11:45:43    

Oki ca me parait pas mal. Je pense que c'est possible en mysql. Je vois pas pourquoi ça serait pas le cas. Moi je dis merci les gars, ça m'enléve une poutre de l'oeil :)

Reply

Marsh Posté le 12-01-2004 à 16:46:26    

Ouais, j'utilise la méthode de JagStang et un arbre pour la manipulation pour quelques sites, je confirme que c'est une méthode parfaitement viable :)

Reply

Marsh Posté le 12-01-2004 à 17:05:12    

j'essaye de faire une fonction pour afficher les categs et sous categs sous forme d'arbre mais sans succés. A vrai dire c'est ma premiere fonction recursive.

Code :
  1. function listcateg($id_parent)
  2. {
  3.   $sql_categmere = "SELECT *
  4.       FROM categorie
  5.       WHERE id_categorie_parent = '" . $id_parent . "'
  6.       ORDER BY nom
  7.          ;";
  8.   $sql_categmere_result = mysql_query($sql_categmere);
  9.   if (mysql_num_rows($sql_categmere_result))
  10.   {
  11.     while($val = mysql_fetch_array($sql_categmere_result))
  12. {
  13.   echo $val["nom"] . "<br />";
  14.   listcateg($val["id_categorie"]);
  15. }
  16.   }
  17.   else
  18.   {
  19.     return 0;
  20.   }
  21. }
  22. listcateg("%" );


 
Y'a quelqu'un qui comprend mieux que moi sachant que la table c'est :
categorie
  -id_categorie
  -id_categorie_parent
  -nom

Reply

Marsh Posté le 12-01-2004 à 17:11:23    

Han, pas de requêtes sql dans une fonction récursive !
 
Tu fais *une* requête pour récupérer le tout *et puis* tu traites le résultat avec une fonction récursive.


---------------
Faux & usage de faux ¤ Machins roses ¤ ASCIImage ¤ HFR Enhance v0.8.6
Reply

Marsh Posté le 12-01-2004 à 17:18:37    

oki, je vais essayer ça :)

Reply

Marsh Posté le 12-01-2004 à 17:25:24    

Si je peux me permettre un conseil : récupère toute la table triée par id_parent de manière à ne pas avoir à chercher la bonne branche que tu y étais déjà pour l'enregistrement précédent :)

Reply

Marsh Posté le 12-01-2004 à 22:44:36    

Je m'arrache les cheveux !

Reply

Marsh Posté le 12-01-2004 à 22:44:36   

Reply

Marsh Posté le 13-01-2004 à 01:22:43    

Ceci t'aidera peut-être :
 

Code :
  1. <?php
  2. // liste des catégories (no,catégorie mère)
  3. $cats = array(
  4. 1 => 0,
  5. 2 => 1,
  6. 3 => 1,
  7. 4 => 0,
  8. 5 => 3,
  9. 6 => 3,
  10. 7 => 5
  11. );
  12. function echoResults($cats,$subcat,$level)
  13. {
  14. // mise en page retrait de ligne
  15. for($i=0;$i<$level;$i++){ $tabs .= " "; }
  16. // pour chaque catégorie...
  17. foreach($cats as $key => $value)
  18. {
  19.  // on regarde si c'est une sous-catégorie de la catégorie en cours
  20.  if($value == $subcat)
  21.  {
  22.   // si oui on l'ajoute
  23.   $output .= $tabs."»".$key."\r\n";
  24.   // puis on regarde si elle a aussi des sous-catégories    
  25.   if(in_array($key,$cats))
  26.   {
  27.    // si oui on relance la fonction pour les trouver
  28.    $output .= echoResults($cats,$key,$level+1);
  29.   }
  30.  }
  31. }
  32. // on sort le résultat
  33. return $output;
  34. }
  35. // initialisation du script et affichage résultat
  36. echo "<pre>\r\n".echoResults($cats,0,0);
  37. ?>


 
edit : commentaires


Message édité par Freekill le 13-01-2004 à 01:29:32

---------------
Faux & usage de faux ¤ Machins roses ¤ ASCIImage ¤ HFR Enhance v0.8.6
Reply

Marsh Posté le 13-01-2004 à 10:35:06    

Parfait je m'en sors bien avec ça :) Je pondais des trucs que je comprenais pas et qui marchait vaguement. Merci beaucoup :)

Reply

Marsh Posté le 13-01-2004 à 10:46:33    

C'est presque bon mais j'ai un décalage dans les catégories...  
 
categ1
categ2
categ3
categ4
categ5
 
Si j'ajoute la categ 5 à la categ 2, la categ 5 est affiché dans la categ 1

Code :
  1. function echoResults($cats,$subcat,$level,$nom)
  2. {
  3.    foreach($cats as $key => $value)// pour chaque catégorie...
  4.    {
  5.      if($value == $subcat)// on regarde si c'est une sous-catégorie de la catégorie en cours
  6.      {
  7.    if($level%2 == 0)
  8.         $output .= "<li>" . $nom["$key"] . "</li>\n";
  9.    else
  10.         $output .= "<ol>" . $nom["$key"] . "</ol>\n";
  11.  
  12.    if(in_array($key,$cats))// puis on regarde si elle a aussi des sous-catégories
  13.    {
  14.          $output .= echoResults($cats,$key,$level+1,$nom);// si oui on relance la fonction pour les trouver
  15.    }
  16.      }
  17.    }
  18.    // on sort le résultat
  19.    return $output;
  20. }


Message édité par kaiska le 13-01-2004 à 11:01:56
Reply

Marsh Posté le 13-01-2004 à 11:12:01    

Voilà pour ceux que ça intêresse j'ai trouvé et ça marche bien. Faut passer un tableau avec le nom des catégories et leurs id en quatriême argument. Voilou voilou et merci beaucoup

Code :
  1. function echoResults($cats,$subcat,$level,$nom)
  2. {
  3.    foreach($cats as $key => $value)// pour chaque catégorie...
  4.    {
  5.      if($value == $subcat)// on regarde si c'est une sous-catégorie de la catégorie en cours
  6.      {
  7.         $output .= "<li>" . $nom["$key"] . "</li>\n";
  8.  
  9.    if(in_array($key,$cats))// puis on regarde si elle a aussi des sous-catégories
  10.    {
  11.          $output .= "<ul>" . echoResults($cats,$key,$level+1,$nom) . "</ul>";// si oui on relance la fonction pour les trouver
  12.    }
  13.      }
  14.    }
  15.    // on sort le résultat
  16.    return $output;
  17. }

Reply

Marsh Posté le 13-01-2004 à 11:53:51    

Quelqu'un sait comment je pourrais faire pour recuperer les categories de tout les niveau au dessus d'une sous categorie à partir d'un numéro de sous catégorie ?
-categ1
-categ2
-categ3
  *categ4
     categ5
  *categ6
du genre a partir de categ5 récupéré :
categ3 > categ4 > categ5

Reply

Marsh Posté le 13-01-2004 à 12:44:17    

Suffit de relancer une boucle/fonction tant que la catégorie parente est supérieure à zero.


---------------
Faux & usage de faux ¤ Machins roses ¤ ASCIImage ¤ HFR Enhance v0.8.6
Reply

Marsh Posté le 13-01-2004 à 13:22:47    

Freekill a écrit :

Suffit de relancer une boucle/fonction tant que la catégorie parente est supérieure à zero.


C'est pas un peu lourd ? Parceque ça m'oblige à récupérer toutes catégories pour pouvoir les traiters. Et faudrait que je fasse ca à chaque page chargé en fait (c'est pour un catalogue)

Reply

Marsh Posté le 13-01-2004 à 13:54:02    

kaiska a écrit :


C'est pas un peu lourd ? Parceque ça m'oblige à récupérer toutes catégories pour pouvoir les traiters. Et faudrait que je fasse ca à chaque page chargé en fait (c'est pour un catalogue)
 


 
Je me demande si tu pourrais pas stocker pour chaque élément une sorte de chemin d'accès sous forme de string, par exemple "categ1/categ5/categ6/" pour une categ 8 qui a pour parent categ6. Ainsi, si tu veux tout les enfants de categ5, il suffit de faire requête qui renvoie que les lignes commencant par "categ1/categ5/". Le problème étant qu'à chaque fois que tu ajoutes ou déplaces une catégorie, faut retrouver tout les parents pour générer cette chaîne ... :/
Ya peut-être un autre moyen ;)
 
Edit: En fait non, j'ai mal lu la question, surtout l'exemple donc c'est pas ce que tu veux


Message édité par Tentacle le 13-01-2004 à 16:59:12
Reply

Marsh Posté le 13-01-2004 à 14:32:26    

hum c'est surement possible mais tout mon systême d'admin pour deplacer les catégories etc est deja en place. La j'arrive à un résultat pas mal.
J'arrive à avoir les categs d'avant. Ca me donne :
categ5 categ1 categ2
mais il faudrait que je puisse inverser se resultat pour afficher un truc du genre
categ2>categ1>categ5
Y'a une fonction pour ça ? surement un explode je pense

Reply

Marsh Posté le 13-01-2004 à 17:01:11    

kaiska a écrit :

hum c'est surement possible mais tout mon systême d'admin pour deplacer les catégories etc est deja en place. La j'arrive à un résultat pas mal.
J'arrive à avoir les categs d'avant. Ca me donne :
categ5 categ1 categ2
mais il faudrait que je puisse inverser se resultat pour afficher un truc du genre
categ2>categ1>categ5
Y'a une fonction pour ça ? surement un explode je pense


Tu as le résultat sous quelle forme ? (c'est quoi la structure des categ dans ton exemple ?)

Reply

Marsh Posté le 13-01-2004 à 17:42:18    

y avait un modèle de table pour un truc du genre ; "rentable" s'il y a une profondeur de 5 au moins (categ > sous-cat > sous-cat > sous-cat > sous-cat)
 
par contre je ne sais plus comment ca s'appelle :(
 
 
il s'agissait de numéroter tous les noeuds et toutes les feuilles à la queue leu leu, les feuilles se voyant attribuer un numéro et les noeuds deux.
 
categ > scat 1 > feuille 1
               > feuille 2
      > scat 2 > feuille 3
               > feuille 4
 
=> categ : min_id = 0
   scat1 : min_id = 1
   feuille1: id = 2
   feuille2: id = 3
   scat1 : max_id = 4
   scat2 : min_id = 5
   feuille3 : id = 6
   feuille4 : id = 7
   scat2 : max_id = 8
   categ : max_id = 9
 
si quelqu'un me comprend  :jap:  
 
 [:spamafote]


Message édité par art_dupond le 13-01-2004 à 17:45:33

---------------
oui oui
Reply

Marsh Posté le 13-01-2004 à 17:47:58    

Mais si tu devais rajouter une feuille, par exemple dans scat1 ... tu fais comment ? tu renumérotes tout ?

Reply

Marsh Posté le 13-01-2004 à 17:49:47    

oui c'est pour ca que ce n'est rentable qu'avec une grande profondeur => rapidité de lecture
 
je crois qu'il y avait aussi une autre condition mais je ne me rappelle plus :/
 
pit etre: pas trop de modification dans la table...


Message édité par art_dupond le 13-01-2004 à 17:50:18

---------------
oui oui
Reply

Marsh Posté le 13-01-2004 à 20:54:48    

Mon projet tutoré de cette année est un ptit site de e-commerce et j'ai été confronté au probleme des sous-catégories.
En fouillant dans mon cote j'ai effectivement une requete sql dans une fonction recursive (pas top...), celle qui me sort les identifiants de toutes les catégories contenues dans celle qu'on passe en argument à la fonction. (ca me permet ensuite de sortir tous les produits contenu dans une catégorie "principale" )
 
Je garde ce topic sous la main, je m'en reservirai l'été prochain, quand je reprendrai le code de mon site (pour l'instant le but c'est que ca marche pour la demonstration à l'oral et que ca soit pas trop une passoire en sécurité, ensuite je l'améliorerai...)

Reply

Marsh Posté le 13-01-2004 à 21:34:42    

si le nombre de niveau de catégories est fixé (categorie, sous cat et sous sous cat ici), pourquoi ne pas faire 3 tables avec des simples jointures ?

Reply

Marsh Posté le 13-01-2004 à 22:07:44    

karamilo a écrit :

si le nombre de niveau de catégories est fixé (categorie, sous cat et sous sous cat ici), pourquoi ne pas faire 3 tables avec des simples jointures ?


 
Oui mais il n'est pas fixé ;)  
(sinon ca serait trop facile :pt1cable: )

Reply

Marsh Posté le 14-01-2004 à 00:12:42    

kaiska a écrit :


J'arrive à avoir les categs d'avant. Ca me donne :
categ5 categ1 categ2
mais il faudrait que je puisse inverser se resultat pour afficher un truc du genre
categ2>categ1>categ5
Y'a une fonction pour ça ? surement un explode je pense


 
un truc genre array_reverse existe si je me souviens bien

Reply

Marsh Posté le 14-01-2004 à 02:01:59    

ethernal a écrit :


 
un truc genre array_reverse existe si je me souviens bien


 
C'est aussi ce que j'ai fait :D  
 
Tu pars de la categorie que tu veux afficher, tu cherche son parent et tu le met dans la table a la suite, puis tu cherche son parent, que tu met dans la table et ainsi de suite...
A la fin tu reverse l'array puis tu genere une belle arborescence :wahoo:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed