Récursivité

cs_eltyty Messages postés 86 Date d'inscription mercredi 31 janvier 2007 Statut Membre Dernière intervention 22 novembre 2011 - 21 déc. 2009 à 18:42
cs_eltyty Messages postés 86 Date d'inscription mercredi 31 janvier 2007 Statut Membre Dernière intervention 22 novembre 2011 - 29 déc. 2009 à 16:47
Bonjour,

Je souhaite faire une boucle récursive afin d'afficher mes rubriques et sous rubriques. Mais pour éviter une trop grande longueur de page je souhaiterai faire ça en deux colonnes quand le nombre de rubrique est trop important.
Voici ma table :
id_rubrique id_parent last (j'indique "oui" quand c'est la dernière rubrique)

Pour ma boucle voici le code ci-dessous qui fonctionne en fonction d'un id passé dans l'url :
CLASS Affichage_recap_rubrique	{
public $liste;
public $erreur;
FUNCTION __construct() {

}



public function Liste_rubriques($parent,$profondeur) {
$connexion =  SPDO::getInstance();


$sql =' SELECT id_rubrique,id_parent,id_groupe,last, titre,archive, statut,descriptif FROM rubriques WHERE id_parent= ? AND id_groupe!="user" AND archive="'.VISUALISER_ARCHIVE.'"';
$sql .=' OR id_parent= ? AND id_groupe="user"';


try{
$select=$connexion->prepare($sql);

$select->bindParam(1,$parent, PDO::PARAM_INT);
$select->bindParam(2,$parent, PDO::PARAM_INT);
}
catch (PDOException $e)        {
throw new myException('la requête préparée est incorrecte');
exit();
}			 
 
$select->execute();
$nb = $select->rowCount();

IF ($nb===0){
RETURN FALSE;
}
//SI DES ENREGISTREMENTS EXISTE
IF ($nb>0) {
WHILE ($fils=$select->fetch(PDO::FETCH_OBJ)) {
$this->titre=$fils->titre;
$this->id_rubrique=$fils->id_rubrique;
$this->id_parent=$fils->id_parent;
$this->last=$fils->last;

//MET UNE MARGE À 0 POUR LA RUBRIQUE PRINCIPALE ET APRÈS ÇA VA DE 40 EN 40
$espace=40*$profondeur;
//SI 'EST LA DENIÈRE RUBRIQUE
//ON MET LE LIEN PUR AFFICHER LA LISTE DES INFOS D'OÙ ACTON=LISTER
IF ($this->last===oui){

$this->liste.= '
[./index.php?p=articles&rub='.$this->id_rubrique.'&action=lister '.$this->titre.']';
$this->liste.= '
';
}
//SI C'EST PAS LA DERNIERE RUBRIQUE
ELSE{

$this->liste.= '
[./index.php?p=articles&rub='.$this->id_rubrique.'&action=recap&nom='.Filtres::enlever_accents($this->titre).' '.$this->titre.']';
$this->liste.= '
';
}
$this->Liste_rubriques($this->id_rubrique,$profondeur + 1);
}
}
}
/*******************************************************************
OBTIENT LE NOM DE LA RUBRIQUE DANS LE GET ET
SON ID_APRENT QUE L'ON ENVOIE À LA FONCTION LISTE_RUBRIQUES
******************************************************************/
PUBLIC function set_rubrique($g_id_rub=NULL){

IF (!EMPTY($g_id_rub)){
$connexion = SPDO::getInstance();
$sql =' SELECT id_parent,titre FROM rubriques WHERE id_rubrique= ? AND id_groupe!="user" ';
$sql .=' OR id_rubrique= ? AND id_groupe="user"';					

try{
$select=$connexion->prepare($sql);
$select->bindParam(1,$g_id_rub, PDO::PARAM_INT);
$select->bindParam(2,$g_id_rub, PDO::PARAM_INT);
}
catch (PDOException $e)        {
throw new myException('la requête préparée est incorrecte');
exit();
}
$select->execute();
$nb_tt =  $select->rowCount();

IF ($nb_tt>0){
$fils=$select->fetch(PDO::FETCH_OBJ);
$g_titre=$fils->titre;
$id_parent=$fils->id_parent;

$this->titre_rubrique= 'Sommaire de '.$g_titre;
//SI ON EST À LA RACINE ON NE MET PAS LE LIEN CAR ON PEUT PAS REMONTER PLUS HAUT
IF ($id_parent>0){

$this->lien=' [./index.php?p=articles&rub='.$id_parent.'&action=recap   ../ ]

';
}
$this->Liste_rubriques($g_id_rub,0);
}
//SI LA RUBRIQUE NE RETOURNE AUCUN ENREGISTREMENT
ELSE{
$this->titre_rubrique = "<center>Aucun élément ne peut être affiché
</center>";
}
}
ELSE {
ECHO 'Valeur incorrecte';
}
}
}



Cette classe marche mais bien sûr tout est en ligne. Et comme la fonction est récursive je ne vois pas comment je peux faire en sorte que ça s'affiche en deux colonnes par exemple. Voici ce que ça donne :
 BAT  
   Liens
   témoignages
 JAVA 
   exemples
      Bout de codes
   témoignages
   
 SQL  
   exercices
      tests
   exemples


Donc si quelqu'un à partir de ce code peut me montrer, merci beaucoup d'avance.

21 réponses

JulSoft Messages postés 354 Date d'inscription dimanche 3 juin 2001 Statut Membre Dernière intervention 11 mars 2013
21 déc. 2009 à 21:27
Peut être qu'on peut faire ça avec un paramètre statique de ta classe comme compteur, et faire des colonnes dans un tableau à partir de ça...
0
cs_eltyty Messages postés 86 Date d'inscription mercredi 31 janvier 2007 Statut Membre Dernière intervention 22 novembre 2011
22 déc. 2009 à 08:31
euh...mais encore ? j'ai mis déjà tellement de temps à faire cette classe...là je vois pas trop comment faire dans ce cas ?
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
22 déc. 2009 à 23:34
Salut,

J'ai pas regarder ton code comme il le faut mais, tu dois partir du principe que lorsque $nb atteindra une valeur limite pour qu'une autre colonne soit crée tu clos le div et, tu crée un autre dans le même principe.
Ne pas oublier, l'attribut float dans ton div pour afficher à droite, à gauche bref comme tu veux!
______________________________________________________________________
0
cs_eltyty Messages postés 86 Date d'inscription mercredi 31 janvier 2007 Statut Membre Dernière intervention 22 novembre 2011
23 déc. 2009 à 19:22
Ok ça je vois bien mais c'est l'incrémentation de $nb qui me semble dur du fait que ca soit une boucle récursive...
Donc si ta moyen de regarder le code dans ce cas ;-)
Merci d'avance.
0

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

Posez votre question
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
24 déc. 2009 à 14:15
Ben, comme je te l'ai dit je n'ai fait que survoler le code mais en faite je vois que $nb ne fait que renvoyer le nombre total d'enregistrement.
Tu pourrais faire par exemple, faire entrer un nouvel objet par exemple :
<?php private $coupet =  0; ?>


et dans if($nb>0) :

 
<?php
if($this->coupet ==($nb/2))
{
   echo '

';
}
else
{
...Ton code normal

$this->coupet++;
}
?>

______________________________________________________________________
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
24 déc. 2009 à 14:22
[quote=Moi]
Tu pourrais faire par exemple, faire entrer un nouvel objet par exemple :
/quote Lol, je reprend :
Tu pourrais faire entrer un nouel objet, par exemple :


J'ai faire un aperçu, j'ai beau me relire, je fais toujours des fautes quelques
______________________________________________________________________
0
kohntark Messages postés 3705 Date d'inscription lundi 5 juillet 2004 Statut Membre Dernière intervention 27 avril 2012 30
24 déc. 2009 à 20:36
"un nouel objet" => contraction de nouvel et Noël ?
"des fautes quelques " => une fois pour ce que n'est moi pas
"J'ai faire un aperçu"

t'as déjà commencé les hostilités vinicoles du réveillon phpAnonyme ?

Bonne soirée,

Kohntark -
(c'est un petit clin d'oeil amical tu l'auras compris)
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
25 déc. 2009 à 01:34
Mais nonnn c'était exprès...humm !

Au passage, bonne fête à toi

Bon, moi je retourne...
______________________________________________________________________
0
hornet_bzz Messages postés 17 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 26 décembre 2009
26 déc. 2009 à 06:53
Hornet bzz 

Salut

Et si tu mémorisais au fur et à mesure ce que tu affiches, et que tu passes cette info lors de l'appel récursif, ça te permettrait d'ajouter un test sur l'affichage .. ?

En voilà une bonne idée !
(Autosatisfaction de Noël)
0
cs_eltyty Messages postés 86 Date d'inscription mercredi 31 janvier 2007 Statut Membre Dernière intervention 22 novembre 2011
28 déc. 2009 à 16:46
Je test des solutions dont celle de phpAnonyme mais là j'ai un peux de mal :-(

Merci déjà pour ces infos et n'hésitez pas à en donner d'autres en exemple. Merci
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
29 déc. 2009 à 01:35
______________________________________________________________________
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
29 déc. 2009 à 02:22
Désolé pour le post vide d'avant, c'est involontaire.

Salut,

Procède ainsi :
<?php
private $limit_elements =  3; // Nombre de rubrique par groupe
private $coupet = 0; // Initialisation pour les groupes
?>


Maintenant, on travaille dans function Liste_rubriques() ,
ICI dans le while juste, après les attributs de la BDD :
<?php
// AJOUT DE MA PART
if($this->coupet ==0 || $this->$coupet==$this->$limit_elements)
{
echo '
';
}
// FIN AJOUT DE MA PART		

   if ($this->last===oui)
   {
   $this->liste.= '
[./index.php?p=articles&rub='.$this->id_rubrique.'&action=lister '.$this->titre.']';
   $this->liste.= '
';
   }
     //SI C'EST PAS LA DERNIERE RUBRIQUE
   else
   {
   $this->liste.= '
[./index.php?p=articles&rub='.$this->id_rubrique.'&action=recap&nom='.Filtres::enlever_accents($this->titre).' '.$this->titre.']';
    $this->liste.= '
';
   }

// AJOUT DE MA PART
      if($this->$coupet==($this->$limit_elements-1))
      {
      echo '
';
      $this->$limit_elements += $this->$limit_elements;		
      }
$this->coupet++;
// FIN AJOUT DE MA PART

$this->Liste_rubriques($this->id_rubrique,$profondeur + 1);
?>


Normalement ça devrait le faire
______________________________________________________________________
0
cs_eltyty Messages postés 86 Date d'inscription mercredi 31 janvier 2007 Statut Membre Dernière intervention 22 novembre 2011
29 déc. 2009 à 08:51
Merci je test tout de suite :-)
0
cs_eltyty Messages postés 86 Date d'inscription mercredi 31 janvier 2007 Statut Membre Dernière intervention 22 novembre 2011
29 déc. 2009 à 08:56
J'ai pour le moment un : Cannot access empty property pour la ligne if($this->$coupet==($this->$limit_elements-1))
Je cherche et je te tiens au courant.
0
cs_eltyty Messages postés 86 Date d'inscription mercredi 31 janvier 2007 Statut Membre Dernière intervention 22 novembre 2011
29 déc. 2009 à 09:23
Cette condition n'est rempli qu'une seule fois : if($this->coupet==0 || $this->coupet==$this->limit_elements)

J'ai fait afficher coupet et limit pour voir et ça donne ça :

element5
coupet0
 BAT 
    Liens
    témoignages
 JAVA 
    exemples

element10
coupet4
   témoignages
   Bout de codes
 SQL 
   exercices
   exemples

element20
coupet9
 PHP 
   Exemples 
   Partiel
    Bruno
    Seb
   complets

Voici ce que j'ai recopié pour avoir ce listing :
private $limit_elements = 5; // Nombre de rubrique par groupe
private $coupet = 0; // Initialisation pour les groupes

// AJOUT DE MA PART
if($this->coupet==0 || $this->coupet==$this->limit_elements){
$this->liste.= '
';
$this->liste.= '
element'.$this->limit_elements;
$this->liste.= '
coupet'.$this->coupet;
}
// FIN AJOUT DE MA PART	


 if ($this->last===oui)
   {
   $this->liste.= '
[./index.php?p=articles&rub='.$this->id_rubrique.'&action=lister '.$this->titre.']';
   $this->liste.= '
';
   }
     //SI C'EST PAS LA DERNIERE RUBRIQUE
   else
   {
   $this->liste.= '
[./index.php?p=articles&rub='.$this->id_rubrique.'&action=recap&nom='.Filtres::enlever_accents($this->titre).' '.$this->titre.']';
    $this->liste.= '
';
   }

// AJOUT DE MA PART
   if($this->coupet==($this->limit_elements-1))    {
      $this->liste.= '
';
      $this->limit_elements += $this->limit_elements;	
 $this->liste.= '
element'.$this->limit_elements;
$this->liste.= '
coupet'.$this->coupet;
   } 
  
// FIN AJOUT DE MA PART

Donc j'essaie de comprendre en même temps mais... ça avance merci encore de m'aider en espérant que ça va finir par marcher.

Merci d'avance.
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
29 déc. 2009 à 14:12
Salut,

Ben pour l'erreur: c'est normal il y a une erreur de frappe de ma part sur les deux variables avec le dollar qui doit être sur $this seulement. Mais bon je vois que t'a corrigé.

Sinon, c'est normal que tu n'est qu'un listing tu as initialisé $limit_elements à 5 ! Si tu n'as pas plus de rubriques tu n'aura pas de deuxième groupe etc etc...
J'avis mis 3 par défaut, mais tu peux jouer avec ou ajouter de nouvelles rubriques...
______________________________________________________________________
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
29 déc. 2009 à 14:19
Ah oui, j'avais oublier :

Une erreur encore de ma part:
<?php
$this->limit_elements += $this->limit_elements ;
?>


Donc ce qu'on va faire c'est laisser $this->limit_elements statiques donc il sera toujours égale à 3, 4 ou 5 ETC....

Et réinitiliser tout simplement $this->coupet !

Ce qui donnera :
<?php
if($this->coupet==($this->limit_elements-1)) {
$this->liste.= '
';
$this->limit_elements += $this->limit_elements;
$this->liste.= '
element'.$this->limit_elements;
$this->liste.= '
coupet'.$this->coupet;

/*ICI on réinitialise*/
$this->coupet=0;
}
else
{
$this->coupet++;
}
?>

______________________________________________________________________
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
29 déc. 2009 à 14:22
Arfff, décidemment !! ilte faut supprimer la ligne :
<?php $this->limit_elements += $this->limit_elements; ?>


______________________________________________________________________
0
cs_eltyty Messages postés 86 Date d'inscription mercredi 31 janvier 2007 Statut Membre Dernière intervention 22 novembre 2011
29 déc. 2009 à 15:12
Ah ca avance, en effet c'est presque bon. Cool car du coup j'ai compris pas mal de truc grâce à cette exemple et ça m'arrange d'enlever
$this->limit_elements += $this->limit_elements;

Donc là ça me sépare bien les rubriques par lot. Maintenant dernière difficulté, je souhaite normalement que la séparation soit faite uniquement sur les rubriques de premier niveau donc mais là je crois que c'est impossible non ? Je sais que j'ai une variable $profondeur qui indique 0 quand c 'est les rubriques principales
WHILE ($fils=$select->fetch(PDO::FETCH_OBJ)) {
/*MET UNE MARGE À 0 POUR LA RUBRIQUE PRINCIPALE ET APRÈS ÇA VA DE 40 EN 40*/
$espace=40*$profondeur;
// AJOUT DE MA PART
if($this->coupet==0 || $this->coupet==$this->limit_elements){
$this->liste.= '
';


if ($this->last===oui)
   {
   $this->liste.= '
[./index.php?p=articles&rub='.$this->id_rubrique.'&action=lister '.$this->titre.']';
   $this->liste.= '
';
   }
     //SI C'EST PAS LA DERNIERE RUBRIQUE
   else
   {
   $this->liste.= '
[./index.php?p=articles&rub='.$this->id_rubrique.'&action=recap&nom='.Filtres::enlever_accents($this->titre).' '.$this->titre.']';
    $this->liste.= '
';
   }

// AJOUT DE MA PART
if($this->coupet==($this->limit_elements-1))    {
$this->liste.= '
';
$this->coupet=0; 
   } 
else {
$this->coupet++;
} 
$this->Liste_rubriques($this->id_rubrique,$profondeur + 1);

}
}

Penses-tu que je peux me servir de $profondeur ? est-ce possible de séparer dans ce cas uniquement les rubriques principales ? et non les sous-rubriques comme actuellement.

En tout cas un gros merci déjà car ça m'avance vraiment quant à mon raisonnement sur les boucles récursives etc. ;-)
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
29 déc. 2009 à 15:55
la séparation soit faite uniquement sur les rubriques de premier niveau
Schématiquement, à quoi cela ressemblerait?

mais là je crois que c'est impossible non ?
Tout est possible ou plûtot presque

______________________________________________________________________
0
Rejoignez-nous