IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Fonction récursive pour affichage arborescence


Sujet :

PHP & Base de données

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    747
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 747
    Points : 168
    Points
    168
    Par défaut Fonction récursive pour affichage arborescence
    Bonjour,

    en back-office, je dois reconstituer l'arborescence d'un menu pour générer un fichier xml du sstyle :

    rubrique 1
    ••sous-rubrique 1
    ••••sous-sous-rubrique 1
    ••sous-rubrique 2
    ••••sous-sous-rubrique 1
    ••••••sous-sous-sous-rubrique 1
    ••••sous-sous-rubrique 2
    rubrique 2
    rubrique 3
    ••sous-rubrique 1

    Dans la base de données chacune des rubriques et sous-rubrique a un id et un cat_father_id, sauf au 1er niveau ou le cat_father_id n'a pas de valeur (normal : il n'y a rien au-dessus).

    Comment faire pour générer le fichier xml ?

    J'ai fait une 1ère boucle qui va chercher les cat_father_id='' (donc toutes les rubriques au 1er niveau)
    Mais c'est après qu'il faudrait que je fasse une boucle qui remonte à chaque palier autant qu'il y a des éléments en cat_father_id.
    Mais je ne sais pas comment écrire ça…


    Votre aide est plus que la bienvenue !

  2. #2
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 193
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 193
    Points : 8 403
    Points
    8 403
    Billets dans le blog
    17
    Par défaut
    Mettons que l'on veut obtenir un XML comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <menu>
        <rubrique label="Rubrique 1">
            <rubrique label="Rubrique 1.1"/>
            <rubrique label="Rubrique 1.2">
                <rubrique label="Rubrique 1.2.1"/>
                <rubrique label="Rubrique 1.2.2"/>
                <rubrique label="Rubrique 1.2.3"/>
            </rubrique>
            <rubrique label="Rubrique 1.3"/>
        </rubrique>
        <rubrique label="Rubrique 2"/>
        <rubrique label="Rubrique 3"/>
    </menu>
    Methode "bateau" gourmande en ressources (une requête SQL à chaque appel de generer_arborescence( )...) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
     
    function generer_arborescence($pere = NULL) 
    {
        if ( $pere === NULL ) {
            $sql = 'SELECT rubrique_id, rubrique_label '
                 . 'FROM rubriques '
                 . 'WHERE rubrique_pere IS NULL' ;
        } else {
            $sql = 'SELECT rubrique_id, rubrique_label, rubrique_pere '
                 . 'FROM rubriques '
                 . 'WHERE rubrique_pere = ' . $pere ;
        }
     
        $rs = mysql_query($sql) ;
        $buffer = '' ;
        while ( $tuple = mysql_fetch_object($rs) ) {
            $buffer .= '<rubrique label="' . htmlentities($rs->rubrique_label) . '">'
                    . generer_arborescence($rs->rubrique_id)
                    . '</rubrique>' ;
        }
     
        return $pere === NULL
            ? "<?xml version='1.0' ?><menu>$buffer</menu>"
            : $buffer ;
    }
     
    header('Content-Type: text/xml') ;
    echo generer_arborescence( ) ;
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    747
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 747
    Points : 168
    Points
    168
    Par défaut
    Merci pour ta réponse Séb.
    Malheureusement pour moi ça ne fonctionne pas encore…
    Ça mouline dans le vide.

    J'ai adapté ton code avec mes paramètres et j'ai sans doute fait une bêtise, non ?
    Voilà ce que j'ai maintenant comme code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    function generer_arborescence($pere = NULL) 
    {
        if ( $pere === NULL ) {
            $sql = 'SELECT cat_id, cat_name '
                 . 'FROM '.$glob['dbprefix'].'CubeCart_category '
                 . 'WHERE cat_father_id = 0' ;
        } else {
            $sql = 'SELECT cat_id, cat_name, cat_father_id '
                 . 'FROM '.$glob['dbprefix'].'CubeCart_category '
                 . 'WHERE cat_father_id = ' . $pere ;
        }
     
        $rs = mysql_query($sql) ;
        $buffer = '' ;
        while ( $tuple = mysql_fetch_object($rs) ) {
            $buffer .= '<rubrique label="' . htmlentities($rs->cat_name) . '">'
                    . generer_arborescence($rs->cat_id)
                    . '</rubrique>' ;
        }
     
        return $pere === NULL
            ? "<?xml version='1.0' ?><menu>$buffer</menu>"
            : $buffer ;
    }
     
    header('Content-Type: text/xml') ;
    echo generer_arborescence( ) ;

  4. #4
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 193
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 193
    Points : 8 403
    Points
    8 403
    Billets dans le blog
    17
    Par défaut
    Oups, à corriger en gras :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    function generer_arborescence($pere = NULL) 
    {
        if ( $pere === NULL ) {
            $sql = 'SELECT cat_id, cat_name '
                 . 'FROM '.$glob['dbprefix'].'CubeCart_category '
                 . 'WHERE cat_father_id = 0' ;
        } else {
            $sql = 'SELECT cat_id, cat_name, cat_father_id '
                 . 'FROM '.$glob['dbprefix'].'CubeCart_category '
                 . 'WHERE cat_father_id = ' . $pere ;
        }
    
        $rs = mysql_query($sql) ;
        $buffer = '' ;
        while ( $tuple = mysql_fetch_object($rs) ) {
            $buffer .= '<rubrique label="' . htmlentities($tuple->cat_name) . '">'
                    . generer_arborescence($tuple->cat_id)
                    . '</rubrique>' ;
        }
        
        return $pere === NULL
            ? "<?xml version='1.0' ?><menu>$buffer</menu>"
            : $buffer ;
    }
    
    header('Content-Type: text/xml') ;
    echo generer_arborescence( ) ;
    Attention à $glob. Si c'est une variable globale il faut faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function ma_fonction( )
    {
        global $glob ;
        ...
    }
    Ou y accéder via $GLOBALS['glob'].
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    747
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 747
    Points : 168
    Points
    168
    Par défaut
    Merci Séb. pour ta réponse. Et désolé d'avoir été insistant…

    Ceci dit ça ne fonctionne toujours pas chez moi, et je n'arrive pas à trouver la raison (mais bon je suis un [Newbie]…).

    Mais si je fais un :
    echo $sql;
    je n'obtiens rien du tout (avec ou sans '.$glob['dbprefix'].' d'ailleurs...).

    Je n'y comprends pas grand chose…

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    747
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 747
    Points : 168
    Points
    168
    Par défaut
    Citation Envoyé par Mister Paul Voir le message
    Mais si je fais un :
    echo $sql;
    je n'obtiens rien du tout
    Si, si j'obtiens bien ce qu'il faut avec echo $sql;
    Mais c'est echo generer_arborescence( ); qui ne renvoie rien

  7. #7
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 193
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 193
    Points : 8 403
    Points
    8 403
    Billets dans le blog
    17
    Par défaut
    Hum, il y a encore des erreurs. Dans mon script je considère qu'une catégorie sans père à cat_father_id à NULL, apparemment en ce qui te conerne c'est plutôt 0 (zéro).
    Donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    function generer_arborescence($pere = 0) 
    {
        $sql = 'SELECT cat_id, cat_name, cat_father_id '
             . 'FROM '.$glob['dbprefix'].'CubeCart_category '
             . 'WHERE cat_father_id = ' . $pere ;
     
        $rs = mysql_query($sql) ;
        $buffer = '' ;
        while ( $tuple = mysql_fetch_object($rs) ) {
            $buffer .= '<rubrique label="' . htmlentities($tuple->cat_name) . '">'
                    . generer_arborescence($tuple->cat_id)
                    . '</rubrique>' ;
        }
     
        return $pere === 0
            ? "<?xml version='1.0' ?><menu>$buffer</menu>"
            : $buffer ;
    }
     
    header('Content-Type: text/xml') ;
    echo generer_arborescence( ) ;
    (on va y arriver )
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    747
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 747
    Points : 168
    Points
    168
    Par défaut
    Merci pour ta patience.
    Euh… on n'y est pas encore…

    - J'ai repris ton dernier script. Il n'a plus le if ( $pere === NULL ) et le else du 1er script que tu avais indiqué : c'est OK comme ça ?

    - J'ai des retours si je mets dans la fonction :
    echo $sql; j'obtiens : "SELECT etc…
    echo $rs; j'obtiens : "Resource id #202 etc…
    echo $tuple; j'obtiens : "Object id #2 etc…

    Mais rien avec : echo $buffer;

  9. #9
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 193
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 193
    Points : 8 403
    Points
    8 403
    Billets dans le blog
    17
    Par défaut
    Il y a aussi cela qui change :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function generer_arborescence($pere = 0)
    Si ça bloque toujours donne-nous un testcase *fonctionnel* ainsi qu'un dump SQL de ta table des catégories.
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    747
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 747
    Points : 168
    Points
    168
    Par défaut
    oui j'ai bien modifié :
    function generer_arborescence($pere = 0)
    et
    return $pere === 0

    Euh c'est quoi un testcase ?
    Fichiers attachés Fichiers attachés

  11. #11
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 193
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 193
    Points : 8 403
    Points
    8 403
    Billets dans le blog
    17
    Par défaut
    Citation Envoyé par Mister Paul Voir le message
    oui j'ai bien modifié :
    function generer_arborescence($pere = 0)
    et
    return $pere === 0
    Parfait.

    Euh c'est quoi un testcase ?
    C'est une portion de code autonome et fonctionnelle qui met le bug en évidence.

    Avec ton dump et cette page :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <?php
        function generer_arborescence($pere = 0) 
        {
            $sql = 'SELECT cat_id, cat_name, cat_father_id '
                 . 'FROM cubecart_category '
                 . 'WHERE cat_father_id = ' . $pere ;
     
            $rs = mysql_query($sql) ;
            $buffer = '' ;
            while ( $tuple = mysql_fetch_object($rs) ) {
                $buffer .= '<rubrique id="' . $tuple->cat_id . '" label="' . htmlentities($tuple->cat_name) . '">'
                        . generer_arborescence($tuple->cat_id)
                        . '</rubrique>' ;
            }
     
            return $pere === 0
                ? "<?xml version='1.0' ?><menu>$buffer</menu>"
                : $buffer ;
        }
     
        header('Content-Type: text/xml') ;
     
        mysql_connect('127.0.0.1', 'root', '') ;
        mysql_select_db('test') ;
     
        echo generer_arborescence( ) ;
    ?>
    J'obtiens bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <?xml version="1.0" ?> 
    <menu>
      <rubrique id="143" label="Jean">
        <rubrique id="134" label="Bigoudaines" /> 
        <rubrique id="135" label="Chemin vers la mer" /> 
        <rubrique id="136" label="Soleil rouge" /> 
        <rubrique id="137" label="bateaux" /> 
      </rubrique>
      <rubrique id="148" label="Jean-Marie">
        <rubrique id="102" label="Irlande-Ecosse">
          <rubrique id="159" label="Irlande">
            <rubrique id="156" label="Irlande du Sud" /> 
            <rubrique id="160" label="Irlande du Nord" /> 
          </rubrique>
          <rubrique id="150" label="Ecosse" /> 
        </rubrique>
        <rubrique id="10" label="Chine" /> 
      </rubrique>
      <rubrique id="149" label="Paul">
        <rubrique id="3" label="Lorem Ipsum" /> 
        <rubrique id="9" label="Corporate">
          <rubrique id="162" label="corpo France" /> 
        </rubrique>
        <rubrique id="152" label="Test1">
          <rubrique id="153" label="Test2">
            <rubrique id="154" label="Test3">
              <rubrique id="155" label="Test4">
                <rubrique id="161" label="Test 5" /> 
              </rubrique>
            </rubrique>
          </rubrique>
        </rubrique>
      </rubrique>
    </menu>
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    747
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 747
    Points : 168
    Points
    168
    Par défaut
    Effectivement ça provient bien de chez moi…
    (ce qui est assez logique)

    J'essaie de combiner ça avec les fopen, fputs, fclose que j'avais avant dans mon code (je ne sais pas si c'est redondant…).
    J'ai tatonné et j'arrive au même résultat que toi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $fp = fopen($glob['rootLocal']."/menuXML_TEST.xml", 'w+');
     
    		fputs($fp, "<?xml version='1.0' ?><menu>");
    		fputs($fp, $buffer);
    		fputs($fp, "</menu>");
    		fclose($fp);
            return $pere === 0
            	? "<?xml version='1.0' ?><menu>$buffer</menu>"
                    : $buffer ;
    Mais euh… globalement dans cette fonction j'ai des trous de compréhension…
    Je ne comprends pas comment lire ça par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    return $pere === 0
            	? "truc bidule"
                    : $buffer
    une bonne âme pour m'expliquer ?
    Ah ces newbies !…

Discussions similaires

  1. Fonction récursive pour affichage progressif.
    Par defacta dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 23/06/2009, 16h22
  2. Réponses: 1
    Dernier message: 15/07/2008, 23h59
  3. Réponses: 6
    Dernier message: 12/04/2007, 20h30
  4. Réponses: 10
    Dernier message: 03/07/2006, 11h32
  5. Fonctions récursives pour parcourir un arbre
    Par mikedavem dans le forum C
    Réponses: 4
    Dernier message: 05/06/2006, 12h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo