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

Langage PHP Discussion :

création d'un tableau de manière récursive?


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 207
    Points : 60
    Points
    60
    Par défaut création d'un tableau de manière récursive?
    Bonjour tout le monde, je souhaiterais créer un tableau contenant la structure d'un ensemble de catégories.

    Une catégorie peut en référencer d'autres, etc…

    Voici un exemple de structure :

    - Catégorie 1
    - Catégorie 1.1
    - Catégorie 1.2
    - Catégorie 1.3
    - Catégorie 1.3.1
    - Catégorie 1.3.2
    - Catégorie 1.4
    - Catégorie 2

    Le but ultime est de créer une treeview de ce type : http://pxp2k4.free.fr/images/treeview.jpg

    Pour cela la première étape est de récupérer les éléments de un tableau, tableau créé dynamiquement.

    =>array
    - Catégorie 1 =>array
    - Catégorie 1.1
    - Catégorie 1.2
    - Catégorie 1.3 =>array
    - Catégorie 1.3.1
    - Catégorie 1.3.2
    - Catégorie 1.4
    - Catégorie 2

    Le soucis est que je ne connais pas d'avance la structure de ce tableau et le nombre de niveau. Par conséquent je pense que je dois faire un parcours récursif.

    Voici mon 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
    //Je récupère les catégories principales
    $list_categories = db_query("SELECT nid, title FROM {node} n
        LEFT JOIN {field_data_field_ordre} fdfo ON n.nid = fdfo.entity_id 
        LEFT JOIN {field_data_field_categorie_principale} fdfcp ON n.nid = fdfcp.entity_id
        WHERE type = :type AND fdfcp.field_categorie_principale_value = :bool_cat_princ ORDER BY fdfo.field_ordre_value", array(":type" => "categorie", ":bool_cat_princ" => 1));
     
        $tree = $categories_node = array();
     
        //Sous catégories
        foreach($list_categories as $record){
            $tree[$record->nid] = $record->nid;
            $category = node_load($record->nid);
            $subcategories = $category->field_sous_categorie;
            $tree[$record->nid] = array();
            for($i=0;$i<sizeof($subcategories);$i++){ 
                $tree[$record->nid][$i] = $subcategories['und'][$i]['nid'];
            } 
        }

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    tu peu donner le print_r($list_categories), pour qu'on voit à quoi cela ressemble ?

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 207
    Points : 60
    Points
    60
    Par défaut
    DatabaseStatementBase Object ( [dbh] => DatabaseConnection_mysql Object ( [shutdownRegistered:protected] => [target:protected] => default [key:protected] => default [logger:protected] => [transactionLayers:protected] => Array ( ) [driverClasses:protected] => Array ( [SelectQuery] => SelectQuery ) [statementClass:protected] => DatabaseStatementBase [transactionSupport:protected] => 1 [transactionalDDLSupport:protected] => [temporaryNameIndex:protected] => 0 [connectionOptions:protected] => Array ( [database] => bdd [username] => pswd [password] => root [host] => localhost [port] => [driver] => mysql [prefix] => Array ( [default] => ) ) [schema:protected] => [prefixes:protected] => Array ( [default] => ) [prefixSearch:protected] => Array ( [0] => { [1] => } ) [prefixReplace:protected] => Array ( [0] => [1] => ) ) [queryString] => SELECT nid, title FROM node n LEFT JOIN field_data_field_ordre fdfo ON n.nid = fdfo.entity_id LEFT JOIN field_data_field_categorie_principale fdfcp ON n.nid = fdfcp.entity_id WHERE type = :type AND fdfcp.field_categorie_principale_value = :bool_cat_princ ORDER BY fdfo.field_ordre_value )

  4. #4
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Points : 2 273
    Points
    2 273
    Par défaut
    Salut,
    le mieux serait un var_dump($record) et/ou surtout que tu nous expliques comment tu stockes tes dépendances entre catégories.
    Un var_dump($category->field_sous_categorie) serait pas mal aussi pour voir ce que fait node_load().

  5. #5
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Points : 2 273
    Points
    2 273
    Par défaut
    Un exemple vite fait depuis un tableau qui ressemble à celui de ton premier post :

    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
    $cats[]['name'] = 'cat 1';
     
    $subs[]['name'] = 'cat 1.1';
    $subs[]['name'] = 'cat 1.2';
    $subs[1]['subs'][]['name'] = 'cat 1.2.1';
     
    $cats[0]['subs'] = $subs;
     
    $cats[]['name'] = 'cat 2';
    $subs2[]['name'] = 'cat 2.1';
    $cats[1]['subs'] = $subs2;
     
     
    echo '<pre>';
    var_dump($cats);
    echo '</pre>';
     
     
    foreach($cats as $cat)   {
        toTree($cat);
    }
     
    function toTree($cat, $rank = 0) {
        echo str_pad('-', $rank + 1, '-');
        echo $cat['name'].'<br>';
        if(isset($cat['subs']))    {
            foreach($cat['subs'] as $sub)   {
                toTree($sub, ++$rank);
            }
        }
    }
    Le rank sert juste à calculer l'étage dans l'arbre.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 207
    Points : 60
    Points
    60
    Par défaut
    var_dump($record) :
    object(stdClass)#107 (2) { ["nid"]=> string(3) "724" ["title"]=> string(12) "Catégorie 1" }
    Ma requête sql me permet de récupérer les catégories principales, celles qui n'ont pas de pères.
    En fait quand je créé une catégorie je peux mentionner une ou plusieurs sous-catégorie.
    C'est pour ça que je réalise un node_load. Cela me permet de voir pour chaque élément si il y a des sous-catégories. Le problème est que il peut avoir des sous-catégorie à l'infini.


    var_dump($category->field_sous_categorie) :
    array(1) { ["und"]=> array(1) { [0]=> array(1) { ["nid"]=> string(3) "784" } } }
    Le nid ça correspond à l'identifiant de l'élément. La catégorie n°724 contient une autre catégorie n° 784

  7. #7
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Points : 2 273
    Points
    2 273
    Par défaut
    En général on stocke plutôt l'id du parent, ce qui permet notamment de récupérer toute l'arborescence en une seule requête mais si je comprends bien ton node_load() fait une requête à chaque fois ?

    Si tu veux pas changer ton modèle de données, il faudrait au moins que node_load() retourne également le 'title' des sous-catégories pour avoir exactement la même structure pour toutes les catégories.

    Ensuite tu peux adapter le code du dessus, ça pourrait donner un truc du style :

    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
     //Roots
    $cats = array();
    foreach($list_categories as $record){
            $cats[] = $record;
    }
     
    $tree = array();
    createTree($cats, $tree);
    echo '$tree<pre>';
    var_dump($tree);
    echo '</pre>';
     
    function createTree($cats, &$tree) {
        foreach($cats as $cat)   {
            $node = array('nid' => $cat['nid'], 'title' => $cat['title']);
            $subCats = node_load($cat['nid']);
            createTree($subCats['und'], $node);
            $tree[] = $node;
        }
    }

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 207
    Points : 60
    Points
    60
    Par défaut
    merci beaucoup, j'ai adapté a ce que je voulais faire, voici mon 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
    function createTree($cats, &$tree) {
            foreach($cats as $cat)   {
                $mon_node = array('nid' => $cat->nid, 'title' => $cat->title);
                $subCats = node_load($cat->nid);
                $cat = array();
                if(isset($subCats->field_sous_categorie['und'])){
                    $sousCats = $subCats->field_sous_categorie['und'];
                    foreach ($sousCats as $sub) {
                        $title = db_query("SELECT title FROM {node} WHERE nid=:nid", array(":nid" =>$sub['nid']))->fetchField();
                        $record->nid = $sub['nid'];
                        $record->title = $title;
                        $cat[] = $record;
                    }
                }
     
                createTree($cat, $mon_node);
                $tree[] = $mon_node;
            }
    }
    VOici le tableau que j'obtiens :

    ... (Array, 4 elements)

    0 (Array, 3 elements)
    nid (String, 3 characters ) 724
    title (String, 12 characters ) Catégorie 1
    0 (Array, 2 elements)
    nid (String, 3 characters ) 784
    title (String, 19 characters ) Sous-Catégorie 1.1
    1 (Array, 2 elements)
    nid (String, 3 characters ) 774
    title (String, 12 characters ) Catégorie 2
    2 (Array, 2 elements)
    nid (String, 3 characters ) 775
    title (String, 12 characters ) Catégorie 3
    3 (Array, 3 elements)
    nid (String, 3 characters ) 777
    title (String, 12 characters ) Catégorie 4
    0 (Array, 3 elements)
    nid (String, 3 characters ) 776
    title (String, 17 characters ) Sous catégorie 4
    0 (Array, 3 elements)
    nid (String, 3 characters ) 783
    title (String, 19 characters ) Sous-Catégorie 4.1
    0 (Array, 2 elements)
    nid (String, 3 characters ) 785
    title (String, 21 characters ) Sous-Catégorie 4.1.1

    Je voudrais désormais afficher l'arborescence des catégories dans une treeview
    de cette façon :
    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
    35
    36
     
    <ul class="treeview">
      <li><span>Categorie 1</span>
    		<ul>
    			<li><span>Categorie 1.0</span>
    				<ul>
    					<li><span>Categorie 1.0.0</span></li>
    				</ul>
    			</li>
    			<li><span>Categorie 1.1</span></li>
    			<li><span>Categorie 1.2</span>
    				<ul>
    					<li><span>Categorie 1.2.0</span>
    					<ul>
    						<li><span>Categorie 1.2.0.0</span></li>
    						<li><span>Categorie 1.2.0.1</span></li>
    						<li><span>Categorie 1.2.0.2</span></li>
    					</ul>
    				</li>
    					<li><span>Categorie 1.2.1</span>
    					<ul>
    						<li><span>Categorie 1.2.1.0</span></li>
    					</ul>
    				</li>
    					<li><span>Categorie 1.2.2</span>
    					<ul>
    						<li><span>Categorie 1.2.2.0</span></li>
    						<li><span>Categorie 1.2.2.1</span></li>
    						<li><span>Categorie 1.2.2.2</span></li>
    					</ul>
    				</li>
    				</ul>
    			</li>
    		</ul>
    	</li>
    </ul>
    Je pense qu'il me faut également un parcours récursif pour récupérer les éléments de mon tableau :

    J'ai essayé ça mais je ne descends que d'un niveau :

    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
    <ul id="gray" class="treeview-gray">
     
    <?php affichageTree($tree); ?>
     
    <?php
    function affichageTree($categories){
    	foreach($categories as $category){
    		$mon_node = array('nid' => $category['nid'], 'title' => $category['title']);
    		$title = $category['title'];
    		echo"<li><span>$title</span>";
        	$subCats = node_load($category['nid']);
        	$cats = array();
        	if(isset($subCats->field_sous_categorie['und'])){
        		$sousCats = $subCats->field_sous_categorie['und'];
            	foreach ($sousCats as $sousCat) {
                	$title = db_query("SELECT title FROM {node} WHERE nid=:nid", array(":nid" =>$sousCat['nid']))->fetchField();
                	$record->nid = $sousCat['nid'];
                	$record->title = $title;
                	$cats[] = $record;
                	echo"<ul><li><span>$title</span></ul>";
            	}
            	//affichageTree($cats);
                echo"</li>";
    		}
     
    	}
    }
     
    ?>

Discussions similaires

  1. [Tableaux] Construire un tableau de manière récursive
    Par eclipse012 dans le forum Langage
    Réponses: 26
    Dernier message: 23/01/2007, 15h59
  2. Création dynamique de tableau.
    Par Yux dans le forum C
    Réponses: 6
    Dernier message: 05/11/2005, 16h24
  3. [XSLT] remplacement de noeuds de manière récursive
    Par daniel_r dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 24/10/2005, 20h13
  4. Création d'un tableau composé de TComboBox
    Par gilles641 dans le forum Langage
    Réponses: 1
    Dernier message: 26/07/2005, 10h30
  5. [Zip] Dézipper de manière récursive
    Par Sfeabg dans le forum Entrée/Sortie
    Réponses: 8
    Dernier message: 08/03/2005, 16h24

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