Récursivité

Signaler
Messages postés
86
Date d'inscription
mercredi 31 janvier 2007
Statut
Membre
Dernière intervention
22 novembre 2011
-
Messages postés
86
Date d'inscription
mercredi 31 janvier 2007
Statut
Membre
Dernière intervention
22 novembre 2011
-
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

Messages postés
354
Date d'inscription
dimanche 3 juin 2001
Statut
Membre
Dernière intervention
11 mars 2013

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...
Messages postés
86
Date d'inscription
mercredi 31 janvier 2007
Statut
Membre
Dernière intervention
22 novembre 2011

euh...mais encore ? j'ai mis déjà tellement de temps à faire cette classe...là je vois pas trop comment faire dans ce cas ?
Messages postés
392
Date d'inscription
mercredi 28 octobre 2009
Statut
Membre
Dernière intervention
23 mars 2012
48
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!
______________________________________________________________________
Messages postés
86
Date d'inscription
mercredi 31 janvier 2007
Statut
Membre
Dernière intervention
22 novembre 2011

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.
Messages postés
392
Date d'inscription
mercredi 28 octobre 2009
Statut
Membre
Dernière intervention
23 mars 2012
48
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++;
}
?>

______________________________________________________________________
Messages postés
392
Date d'inscription
mercredi 28 octobre 2009
Statut
Membre
Dernière intervention
23 mars 2012
48
[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
______________________________________________________________________
Messages postés
3706
Date d'inscription
lundi 5 juillet 2004
Statut
Membre
Dernière intervention
27 avril 2012
30
"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)
Messages postés
392
Date d'inscription
mercredi 28 octobre 2009
Statut
Membre
Dernière intervention
23 mars 2012
48
Mais nonnn c'était exprès...humm !

Au passage, bonne fête à toi

Bon, moi je retourne...
______________________________________________________________________
Messages postés
17
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
26 décembre 2009

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)
Messages postés
86
Date d'inscription
mercredi 31 janvier 2007
Statut
Membre
Dernière intervention
22 novembre 2011

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
Messages postés
392
Date d'inscription
mercredi 28 octobre 2009
Statut
Membre
Dernière intervention
23 mars 2012
48
______________________________________________________________________
Messages postés
392
Date d'inscription
mercredi 28 octobre 2009
Statut
Membre
Dernière intervention
23 mars 2012
48
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
______________________________________________________________________
Messages postés
86
Date d'inscription
mercredi 31 janvier 2007
Statut
Membre
Dernière intervention
22 novembre 2011

Merci je test tout de suite :-)
Messages postés
86
Date d'inscription
mercredi 31 janvier 2007
Statut
Membre
Dernière intervention
22 novembre 2011

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.
Messages postés
86
Date d'inscription
mercredi 31 janvier 2007
Statut
Membre
Dernière intervention
22 novembre 2011

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.
Messages postés
392
Date d'inscription
mercredi 28 octobre 2009
Statut
Membre
Dernière intervention
23 mars 2012
48
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...
______________________________________________________________________
Messages postés
392
Date d'inscription
mercredi 28 octobre 2009
Statut
Membre
Dernière intervention
23 mars 2012
48
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++;
}
?>

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


______________________________________________________________________
Messages postés
86
Date d'inscription
mercredi 31 janvier 2007
Statut
Membre
Dernière intervention
22 novembre 2011

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. ;-)
Messages postés
392
Date d'inscription
mercredi 28 octobre 2009
Statut
Membre
Dernière intervention
23 mars 2012
48
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

______________________________________________________________________