Fonction récursive et enregistrement ds tableau[ ] :-/ ? [Résolu]

Messages postés
13
Date d'inscription
vendredi 7 septembre 2007
Dernière intervention
17 septembre 2007
- 9 sept. 2007 à 22:13 - Dernière réponse :
Messages postés
13
Date d'inscription
vendredi 7 septembre 2007
Dernière intervention
17 septembre 2007
- 10 sept. 2007 à 21:32
Bonjour,

J'ai une table mysql avec ceci :

category_id - category - parent_num
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

Je souhaite donc faire un fil d'ariane. J'ai abouti à cette fonction :

// Fil d'Ariane
$category_id = $db_data['category_id'];
echo $category_id; // affiche bien l'id de la catégorie en cours

function getTopParent($pi_current, $pa_data)
        {

            // sql + query
            $sSql = "SELECT parent_num, category FROM categories WHERE category_id=$pi_current";
            $req = mysql_query($sSql) or die(mysql_error());

            if (mysql_num_rows($req)>0)
            {
                $aData = mysql_fetch_assoc($req);
                $pa_data = array($aData);
                getTopParent($aData['parent_num'], $pa_data);
            }
        }

        // Appel de la function
        getTopParent($category_id, $pa_data) ;
       
        // Reverse l'ordre des resultats pour avoir en premier le root
        $aFinalData = array_reverse($pa_data) ; 

// pour parcourir ce tableau, utilisons la boucle foreach
foreach($individu as $cle=>$valeur)
    {
    echo $cle.' : '.$valeur.'
';
    } 


Mais cela me sort ce message d'erreur :

Warning: array_reverse() [function.array-reverse]: The argument should be an array

pour la ligne correspondant à :

$aFinalData = array_reverse($pa_data) ;


Le problème semble venir de (la mauvaise) insertion des données dans le tableau, car lorsque je fais seulement:

function getTopParent($pi_current, $pa_data)
        {

            // sql + query
            $sSql = "SELECT parent_num, category FROM categories WHERE category_id=$pi_current";
            $req = mysql_query($sSql) or die(mysql_error());

            if (mysql_num_rows($req)>0)
            {
                $aData = mysql_fetch_assoc($req);
                echo $aData['category'];
                getTopParent($aData['parent_num'], $pa_data);
            }
        }

        // Appel de la function
        getTopParent($category_id, $pa_data) ;


Cela m'affiche bien le nom de mes catégories, mais dans l'ordre inverse d'un fil d'ariane (à gauche il y a la catégorie la plus basse dans la hiérarchie et à droite la plus haute, alors que ça devrait bien sûr être l'inverse pour un fil d'ariane...). D'où l'idée de stocker les données dans un tableau pour ensuite inverser le tableau et afficher les données (si vous avez mieux je suis tout autant preneur :) ).

J'ai cherché avec mon ami Google les cours présentant la mise en tableau de données, mais je n'ai pas réussi à comprendre où était l'erreur dans mon code :-/... Je suppose pourtant que la bêtise est évidente :- ?

Pourriez-vous m'aider s'il vous plait :- ?
Afficher la suite 

Votre réponse

16 réponses

Meilleure réponse
Messages postés
12336
Date d'inscription
mardi 10 février 2004
Dernière intervention
30 juillet 2012
- 10 sept. 2007 à 19:28
3
Merci
Salut

function getTopParent($pi_current, &$pa_data)
        {
             // sql + query
            $sSql = "SELECT parent_num, category FROM categories WHERE category_id=$pi_current";
            $req = mysql_query($sSql) or die(mysql_error());
 
            if (mysql_num_rows($req)>0)
            {
                $aData = mysql_fetch_assoc($req);
                $pa_data[]=$aData;
                getTopParent($aData['parent_num'], $pa_data);
            }
        }

apres avoir fait ton appel de fonction

foreach ($tableau as $a){
echo $a['...'].' =>'.$a['...'];
}

<hr />une recherche sur exalead vous aurait peut-etre evite de poser cette question

In a dream, I saw me, drop dead...
U were there, U cried...
It was just a dream,
if I die, U won't cry, maybe, U'll be happy

Merci coucou747 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 87 internautes ce mois-ci

Commenter la réponse de coucou747
Messages postés
2268
Date d'inscription
mercredi 27 novembre 2002
Dernière intervention
13 septembre 2013
- 9 sept. 2007 à 22:51
0
Merci
Salut!
 Il y a qqch que je comprend pas: mysql_fetch_assoc te renvoie un tableau... Pourquoi créer un autre tableau (à un seul indice) contenant ce tableau?

Ne pourrais tu pas juste faire:
$pa_data = mysql_fetch_assoc($req);
getTopParent($aData['parent_num'], $pa_data);

@++

R@f

La boîte à bouts de codes
"On dit que seulement 10 personnes au monde comprenaient Einstein. Personne ne me comprends. Suis-je un génie???"
Commenter la réponse de coockiesch
Messages postés
13
Date d'inscription
vendredi 7 septembre 2007
Dernière intervention
17 septembre 2007
- 9 sept. 2007 à 22:59
0
Merci
Bonsoir,

Merci pour ta suggestion coockiesch !
Malheureusement si je fais :

            if (mysql_num_rows($req)>0)
            {
                $aData = mysql_fetch_array($req);
                $pa_data = mysql_fetch_assoc($req);
                getTopParent($aData['parent_num'], $pa_data);
            }

Ca me renvoit toujours l'erreur " Warning : array_reverse() [function.array-reverse]: The argument should be an array" sur la ligne "$aFinalData = array_reverse($pa_data) ; " :-(...
Commenter la réponse de yazerty55
Messages postés
2268
Date d'inscription
mercredi 27 novembre 2002
Dernière intervention
13 septembre 2013
- 9 sept. 2007 à 23:06
0
Merci
Je comprend pas: mysql_fetch_assoc te renvoie un tableau, pouquoi tu veux absolument le bidouiller?
$pa_data = mysql_fetch_assoc($req);
getTopParent($pa_data, $pa_data);

Pcq, si tu fais:
getTopParent($aData['parent_num'], $pa_data);
$aData est un tableau, mais pas $aData['parent_num']....

@++

R@f

La boîte à bouts de codes
"On dit que seulement 10 personnes au monde comprenaient Einstein. Personne ne me comprends. Suis-je un génie???"
Commenter la réponse de coockiesch
Messages postés
13
Date d'inscription
vendredi 7 septembre 2007
Dernière intervention
17 septembre 2007
- 9 sept. 2007 à 23:16
0
Merci
Je ne suis pas sûr de comprendre quelle forme finale tu suggères je crois (désolé :-/). Pourrais-tu remettre la partie du

if (mysql_num_rows($req)>0)
            {
            }

telle que tu me suggère afin que j'y vois plus clair dans la démarche s'il te plait :- ?
Commenter la réponse de yazerty55
Messages postés
2268
Date d'inscription
mercredi 27 novembre 2002
Dernière intervention
13 septembre 2013
- 9 sept. 2007 à 23:19
0
Merci
Ca?
if (mysql_num_rows($req)>0)
      {
                $aData = mysql_fetch_assoc($req);
                getTopParent($aData['parent_num'], $aData);
            }

@++

R@f

La boîte à bouts de codes
"On dit que seulement 10 personnes au monde comprenaient Einstein. Personne ne me comprends. Suis-je un génie???"
Commenter la réponse de coockiesch
Messages postés
13
Date d'inscription
vendredi 7 septembre 2007
Dernière intervention
17 septembre 2007
- 9 sept. 2007 à 23:32
0
Merci
Merci pour ton aide !

Mmm' alors non ça ne marche pas non plus quand je fais ça :-( :

------------------
// Fil d'Ariane
$category_id = $db_data['category_id'];
echo $category_id; // affiche bien l'id de la catégorie en cours
 
function getTopParent($pi_current, $pa_data)
        {
 
            // sql + query
            $sSql = "SELECT parent_num, category FROM categories WHERE category_id=$pi_current";
            $req = mysql_query($sSql) or die(mysql_error());
 
            if (mysql_num_rows($req)>0)
            {
                $aData = mysql_fetch_assoc($req);
                echo $aData['parent_num']; // Affiche bien les id des catégories parentes de celles qui doivent s'afficher
                getTopParent($aData['parent_num'], $aData);
            }
        }
 
        // Appel de la function
        getTopParent($category_id, $aData) ;
      
        // Reverse l'ordre des resultats pour avoir en premier le root
        $aFinalData = array_reverse($aData) ;
 
// pour parcourir ce tableau, utilisons la boucle foreach
foreach($individu as $cle=>$valeur)
    {
    echo $cle.' : '.$valeur.'
';
    }
------------------
(j'ai mis $aData à la place de pa_Data du coup pour la suite du code).

ps : par contre je crois que je vois ce que tu m'explique avec le tableau qu'il ne sert à rien de recréer puisque mysql_fetch_assoc en crée un lui-même.
Commenter la réponse de yazerty55
Messages postés
2268
Date d'inscription
mercredi 27 novembre 2002
Dernière intervention
13 septembre 2013
- 9 sept. 2007 à 23:33
0
Merci
J'y réfléchis et je te redis demain, si c'est pas réglé par qlqn d'autre d'ici là!...

@++

R@f

La boîte à bouts de codes
"On dit que seulement 10 personnes au monde comprenaient Einstein. Personne ne me comprends. Suis-je un génie???"
Commenter la réponse de coockiesch
Messages postés
13
Date d'inscription
vendredi 7 septembre 2007
Dernière intervention
17 septembre 2007
- 9 sept. 2007 à 23:36
0
Merci
Merci, et bonne nuit ;-) !
Commenter la réponse de yazerty55
Messages postés
12336
Date d'inscription
mardi 10 février 2004
Dernière intervention
30 juillet 2012
- 10 sept. 2007 à 06:33
0
Merci
Salut

ta fonction ne renvoie rien... faut alors passer ce param par reference, ce qui implique de le declarer plus tot...

function getTopParent($pi_current, &$pa_data)
        {
 
            // sql + query
            $sSql = "SELECT parent_num, category FROM categories WHERE category_id=$pi_current";
            $req = mysql_query($sSql) or die(mysql_error());
 
            if (mysql_num_rows($req)>0)
            {
                $aData = mysql_fetch_assoc($req);
                $pa_data[]=$aData['parent_num'];
                getTopParent($aData['parent_num'], $pa_data);
            }
        }

tu l'appelles en faisant :

$aData=array();
        // Appel de la function
        getTopParent($category_id, $aData) ;
      
        // Reverse l'ordre des resultats pour avoir en premier le root
        $aFinalData = array_reverse($aData) ;
 
// pour parcourir ce tableau, utilisons la boucle foreach
foreach($individu as $cle=>$valeur)
    {
    echo $cle.' : '.$valeur.'
';
    }

sinon, si tu utilises mysql5, tu peux peut-etre utiliser une fonction sql...

CREATE FUNCTION menu_deroule(id INT UNSIGNED)
RETURNS TEXT DETERMINISTIC
BEGIN
  DECLARE t TEXT;
  DECLARE r TEXT;
  DECLARE i INT UNSIGNED;
  SET i = id;
  SET t = "";
  SET r = "";
  WHILE i!=0 AND ISNULL(i)=0
  DO
    SELECT `child_of`, `titre` INTO i, t FROM `menu` WHERE menu.id=i;
    SET r = CONCAT(t, "/", r);
    IF i = id THEN
      SET i=0;
    END IF;
  END WHILE;
  RETURN r;
END;

pour ma fonction, j'avais une table :
id           child_of               titre
et je recuperais les titres separes par des /

<hr />une recherche sur exalead vous aurait peut-etre evite de poser cette question

In a dream, I saw me, drop dead...
U were there, U cried...
It was just a dream,
if I die, U won't cry, maybe, U'll be happy
Commenter la réponse de coucou747
Messages postés
13
Date d'inscription
vendredi 7 septembre 2007
Dernière intervention
17 septembre 2007
- 10 sept. 2007 à 07:21
0
Merci
Merci beaucoup coucou747 : ça marche !! Je me réveille de très bonne humeur grâce à toi :-).
Par contre je ne comprends pas la logique du foreach dans ce cadre là. Je ne vois pas comment faire correspondre les valeurs que je dois utiliser ensemble.
En effet sur mon fil d'ariane je vais bien sûr faire des liens vers chacun des item du fil. Les liens sont constitués de l'id de la catégorie.

Cependant en exécutant ce code php :
            if (mysql_num_rows($req)>0)
            {
                $aData = mysql_fetch_assoc($req);
                $pa_data[]=$aData['category'];
                $pa_data[]=$aData['parent_num'];
               
                getTopParent($aData['parent_num'], $pa_data);
            }
        }

$aData=array();
// Appel de la function
getTopParent($parent_num, $aData) ;
     
// Reverse l'ordre des resultats pour avoir en premier le root
$aFinalData = array_reverse($aData) ;

 foreach($aFinalData as $cle=>$valeur)
    {
    echo $cle.' : '.$valeur.'
';
    }

J'obtiens à l'affichage :
0 : 0
1 : Loisirs & divertissement
2 : 16
3 : Sport
4 : 22
5 : Rugby

La catégorie "Loisirs" porte l'id 16 et "Sport" l'id 22. Je connais l'id de "Rugby", c'est celui de la catégorie en cours.
Il me faut donc cet id lorsque j'affiche "Loisirs" et "Sport" (mais cela peut être pour plus de niveaux, il n'y a pas de limite). Je ne comprends pas comment faire pour avoir la valeur de la boucle suivante pour faire mon lien sur le nom de la catégorie ?
Commenter la réponse de yazerty55
Messages postés
12336
Date d'inscription
mardi 10 février 2004
Dernière intervention
30 juillet 2012
- 10 sept. 2007 à 07:49
0
Merci
Salut
remplace :
                $pa_data[]=$aData['category'];
                $pa_data[]=$aData['parent_num'];
par
                $pa_data[$aData['parent_num']]=$aData['category'];

et regarde bien ma requete sql, elle peut te permettre de ne faire qu'une requete, et de gagner en temps de generation de ta page...
<hr />une recherche sur exalead vous aurait peut-etre evite de poser cette question

In a dream, I saw me, drop dead...
U were there, U cried...
It was just a dream,
if I die, U won't cry, maybe, U'll be happy
Commenter la réponse de coucou747
Messages postés
13
Date d'inscription
vendredi 7 septembre 2007
Dernière intervention
17 septembre 2007
- 10 sept. 2007 à 16:05
0
Merci
Ca ne me rentre par le numéro de la catégorie dans la "$cle" bizarrement avec :

function getTopParent($pi_current, &$pa_data)
        {
             // sql + query
            $sSql = "SELECT parent_num, category FROM categories WHERE category_id=$pi_current";
            $req = mysql_query($sSql) or die(mysql_error());
 
            if (mysql_num_rows($req)>0)
            {
                $aData = mysql_fetch_assoc($req);
                $pa_data[$aData['parent_num']]=$aData['category'];
                getTopParent($aData['parent_num'], $pa_data);
            }
        }

$aData=array();
// Appel de la function
getTopParent($parent_num, $aData) ;
     
// Reverse l'ordre des resultats pour avoir en premier le root
$aFinalData = array_reverse($aData) ;
   
    {
    echo $cle.' : '.$valeur.'
';
    }

Ca affiche :
0 : Loisirs & divertissement
1 : Sport
2 : Rugby

J'ai essayé en faisant $pa_data[$pi_current]=$aData['category']; (cf requête SQL) mais cela ne donne rien (le résultat est le même).
Mais je ne comprends pas pourquoi on inverse aData et pas padata dans la suite du code :-? Mais si on inverse pa_data ça rend une erreur (array_reverse() : The argument should be an array
Est-ce bon de ce côté là :-?
ps : pour la fonction Mysql j'ai une base Mysql 5.0 (1&1 en mutualisé). Je regarderais les fonctions Mysql et verrai si je change de stratégie, mais pour le moment cela me parait un peu complexe à la vue de mon niveau actuel (de plus l'aide sur internet sur ce genre de fonction est moins présente que les cours de php :). Mais merci de me signaler qu'il y a plus efficace et performant :) (au pire je mettrai en place un système de cache sur mes pages :).
Commenter la réponse de yazerty55
Messages postés
13
Date d'inscription
vendredi 7 septembre 2007
Dernière intervention
17 septembre 2007
- 10 sept. 2007 à 20:45
0
Merci
MERCI COUCOU747 :-))) !!! Merci Merci Merci :-) !!!!
Commenter la réponse de yazerty55
Messages postés
1982
Date d'inscription
dimanche 20 février 2005
Dernière intervention
24 septembre 2012
- 10 sept. 2007 à 21:19
0
Merci
Hello, tu peux aussi accepter sa réponse :)
Commenter la réponse de Evangun
Messages postés
13
Date d'inscription
vendredi 7 septembre 2007
Dernière intervention
17 septembre 2007
- 10 sept. 2007 à 21:32
0
Merci
Ah ui, désolé je suis nouveau sur ce forum ;-).
 Pratique !
Commenter la réponse de yazerty55

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.