Création menu

agparchitecture Messages postés 88 Date d'inscription jeudi 9 mars 2006 Statut Membre Dernière intervention 7 novembre 2010 - 26 juil. 2010 à 11:20
RaftY Messages postés 56 Date d'inscription mardi 5 mars 2002 Statut Membre Dernière intervention 12 août 2010 - 26 juil. 2010 à 15:26
Bonjour à tous, je me tourne une nouvelle fois vers vous car vos conseil et avis sont judicieux...

Je souhaite faire réaliser un menu dynamique avec possibilité de sous menu "infini" depuis une base de données Mysql.

La base de données contient :
Id-> identifiant du menu
Position -> La position dans le menu
texte -> Texte à afficher pour le menu
.... -> d'autre élément inutile à mon avis pour le problème

La valeur position se compose d'un chiffre, un point, un chiffre, un point et ainsi de suite.... ce qui me permet de les classer par ordre croissant
exemple:

1 (Menu 1)
1.1 (sous-menu de 1 point 1)
1.1.1 (sous-menu de 1.1 point1)
1.1.2 (sous-menu de 1.1 point2)
1.2 (sous-menu de 1 point 2)
2 (Menu 2)
2.1 (sous-menu de 2 point 1)
2.1.1 (sous-menu de 2.1 point 1)
2.1.1.1 (sous-menu de 2.1.1 point 1)
etc...

sur base de ces valeurs, je souhaiterais pouvoir construire le menu avec de et des <li>

Malheureusement je ne vois pas comment réaliser la structure de mon algorithme de traitement pour que celle-ci soit récursives.

Je suis donc ouvert à toutes suggestion de votre part et merci de votre aide.

5 réponses

RaftY Messages postés 56 Date d'inscription mardi 5 mars 2002 Statut Membre Dernière intervention 12 août 2010
26 juil. 2010 à 12:51
Bonjour,

Premièrement tu pars d'une basse de données donc par définition un tableau 2D en sortie! Mais il y a plusieurs façon de voir la base de données et pas uniquement 2D.

Pour résoudre ton problème, je vois Trois axes possibles et je suis persuadé qu'il y en aura autant que de personnes qui souhaitent répondre.


1- 2 étapes:
On peut voir la sortie de la base de données par requete , comme un tableau 2D. Une fonction va traiter le tableau 2D pour en faire un Arbre PHP. Un arbre PHP n'est rien d'autre qu'un tableau multidimmension.

Ex d'arbre PHP:
 $arbre["racine"]=array();
 $arbre["racine"]["noeud1"]=array("feuille"=>1);
 $arbre["racine"]["noeud2"]=array("noeud 2.1"=>array("feuille"=>1), "noeud 2.2"=>array("feuille"=>1), "noeud 2.3"=>array("noeud2.3.1"=>array("feuille"=>1)));


En bref, découper en fonction de l'indice pour créer un tableau multidimensionnel, on entre avec $lst (tableau issu de la requete) et $sep le séparateur, si on souhaite en changer juste ce param est à changer:

function 2DtoTree($lst, $sep)
{
 $out=array();
 foreach ($lst as $k=>$v)
  {
   $indices= explode($sep, $k);
   $treeTxt="$out";
   foreach($indices as $ind)
    {
     $treeTxt.="[".$ind."]";
    }
   $treeTxt.="=".$v;
   eval($treeTxt);
  }

return $out;
}

{Code non testé}

Method pas super Elegante mais très efficace qui cree les node du tableau en mode text le tableau et qu'il le fait évaluer. Ensuite on a un arbre, qui marche en récursif avec le test d'arret "is_array($out)"

2- BDD récursive
Le concept est différent, il partir du principe que l'on interrogera la base de données par niveau en mode récursif. On entre dans la fonction avec les indices de premier niveau (SELECT * FROM TABLE WHERE IND NOT LIKE '%.%'), ensuite à chaque passage récursif, on teste la condition d'arret:
SELECT * FROM TABLE WHERE IND LIKE '$indCur.%', si des enregistrements sont renvoyé on entre récursion, sinon on s'arrête.

3- Itératives
L'idée en itératif sera de savoir quand on ferme les UL, LI et savoir quand on les ouvres.

Je propose de passer en revue la liste avec un foreach par exemple (un while marchera aussi) et en fait on va compte le nombre de séparateur (ici '.'). Si le nombres de séparateur courant ($nbSepCur) soustrait du nombre de séparateur précédent ($nbSepOld) => ($nbUL=$nbSepCur-$nbSepOld, normalement si la base est bien triées) est positive alors j'ajoute autant de UL que cette différence ($nbUL), si elle est négative j'ajoute autant de /UL que cette différence, sinon on en ajoute pas.
Puis à chaque passage de boucle <li>$val</li>

Bon courage!

______oOOO________OOOo________

RaftY, du code C commode!
0
agparchitecture Messages postés 88 Date d'inscription jeudi 9 mars 2006 Statut Membre Dernière intervention 7 novembre 2010
26 juil. 2010 à 14:06
Merci pour le conseil cependant, je me pose quelques questions:

1. C'est ce que j'essaye d'implémenter actuellement, mais je ne vois pas comment faire pour fermer les si je ne suis plus dans un sous menu avec le noeud précédent

2. Base de données récursives: Est-ce que ce n'est pas un peu lourd de faire plusieurs requête afin de les traiter...

3- Itératives : Alors la je ne comprend pas du tout... Est-ce qu'il serait possible d'avoir un peu plus d'explication s'il vous plait?

Merci pour le coup de main
0
agparchitecture Messages postés 88 Date d'inscription jeudi 9 mars 2006 Statut Membre Dernière intervention 7 novembre 2010
26 juil. 2010 à 14:17
0
RaftY Messages postés 56 Date d'inscription mardi 5 mars 2002 Statut Membre Dernière intervention 12 août 2010
26 juil. 2010 à 15:25
1- Pour refermer on utilise la post récursivité, c'est à dire les traitemnt par dépilement

Ex:

function recu($lst)
{
$ret= "";
 foreach($lst as $k=> $v)
  {
    if(is_array($v))
     {
      $ret.=""; //s'execute avant recurs
      $ret.=recu($v);
      $ret.=""; //s'execute après recurs, une fois tout le traitement descendant fait donc bien placer pour fermer le UL
     }
   else
     {
      $ret.="<li>".$v."</li>";
     }
  }
 return $ret;
}

{Code non testé}

2. Cela dépend des objectifs, faire des requete à chaque est lourd par rapport à un traitement classique en une fois. En revanche, dans l'objectif de le migrer vers de l'utilisation Ajax avec appel du prog pour chaque niveau, ce n'est pas dénuer de bon sens.

3. Le principe est voir ex:

/* $lst considérer de la forme suivante:
    [IND][LIB]
     1    Menu 1
     1.1  Sous Menu 1.1
     2    Menu 2 ....
*/

//init
$sep =".";
$nbSepOld=0;
$out="";

//bouclage sur la list
foreach($lst as $k=>$v)
{
 $nbSepCur=count(explode($sep, $v["IND"])); //compte le nombre d'élement du tableau séparer par $sep
  $nbUL=$nbSepCur-$nbSepOld; //récupère la différence de niveau
  if($nbUL>0)
   {
    for($i=0; $i<$nbUl; $i++)
     {
      $out.="\n"; //applique les UL entrants
     }
   }

if($nbUL<0)
   {
    for($i=0; $i<-$nbUl; $i++)
     {
      $out.="\n"; //applique les UL sortants
     }
   }

$nbSepOld=$nbSepCUr;
$out.="<LI>".$v."</LI>";
}

echo $out;


{Code non testé}

______oOOO________OOOo________

RaftY, du code C commode!
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
RaftY Messages postés 56 Date d'inscription mardi 5 mars 2002 Statut Membre Dernière intervention 12 août 2010
26 juil. 2010 à 15:26
$nbSepOld=$nbSepCUr;
$out.="<LI>".$v."</LI>";


il faut lire

$nbSepOld=$nbSepCUr;
$out.="<LI>".$v["lib"]."</LI>";


______oOOO________OOOo________

RaftY, du code C commode!
0
Rejoignez-nous