8797 sujets

Développement web côté serveur, CMS

Bonjour,

Je réalise un script en php afin d'aller chercher dans ma base de données les catégories mere de mon site, ensuite il va chercher les sous catégorie, puis les sous catégories de deuxième niveau.

Voici mon premier script qui fonctionne mais qui a deux inconvénient:
- je répète trois fois la même chose (grosso-modo)
- le script s'arrête au deuxième sous-niveau et s'il y en a 15, je dois écrire 15 fois la même chose.


// J'afiche toutes les catégories.				
$req_cat_mere1 = mysql_query("SELECT * FROM categories_annuaire WHERE id_categorie_mere='0' order by nom_categorie") or die(mysql_error());  // Requête SQL							
				
   echo '<ul>';				
   while($categorie_mere1 = mysql_fetch_array($req_cat_mere1))
     {
	$id_categorie_mere1 = $categorie_mere1 ['id'];
	 echo '<li>' .$categorie_mere1 ['nom_categorie']. '</li>';
				  
		// J'afiche toutes les sous-catégories				
		$req_cat_mere2 = mysql_query("SELECT * FROM categories_annuaire WHERE id_categorie_mere='$id_categorie_mere1' order by nom_categorie") or die(mysql_error());  // Requête SQL								
						
		echo '<ul>';				
		while($categorie_mere2 = mysql_fetch_array($req_cat_mere2))
		 {
	        	  $id_categorie_mere2 = $categorie_mere2 ['id'];
			  echo '<li>' .$categorie_mere2 ['nom_categorie']. '</li>';
						  
		                // J'afiche toutes les sous-catégories de niveau-2				
				$req_cat_mere3 = mysql_query("SELECT * FROM categories_annuaire WHERE id_categorie_mere='$id_categorie_mere2' order by nom_categorie") or die(mysql_error());  // Requête SQL								
								
				echo '<ul>';				
				while($categorie_mere3 = mysql_fetch_array($req_cat_mere3))
				 {
					  $id_categorie_mere3 = $categorie_mere3 ['id'];
					  echo '<li>' .$categorie_mere3 ['nom_categorie']. '</li>';
				 }	
								 			 
				echo '</ul>';
		 }				 
		echo '</ul>';
 }				 
echo '</ul>';								  
?>


Comme je l'ai dis si dessus mon code ce répète trois fois pour le niveau1, le niveau2 et le niveau3 et s'il y a plus de 3 niveau ce ne marchera plus ou du moins cela s'arrêtera au troisième niveau.

J'ai donc essayé de réalisé ce même script avec des variables variables, puisqu'il n'y a que les niveau qui change dans le code ci-dessus, mais je ne parviens pas à mes fin.

Voici le code qui ne marche pas. (ça tourne en boucle j'ai l'impression)



$niveau = 0; // J'nitialise le niveau de la categorie				
$id_categorie_mere = 0; //J'initialise ma variable id_categorie_mere
$nb_sous_categories != 1  // Pour lancer la premiere bouble. 				
				
while($nb_sous_categories != 0)
   {								
	// J'afiche toutes les catégories.				
	$req_cat_mere{$niveau} = mysql_query("SELECT nom_categorie, id, id_categorie_mere FROM categories_annuaire WHERE id_categorie_mere='$id_categorie_mere' order by nom_categorie") or die(mysql_error());  // Requête SQL
					
	// Je compte le nombre de resultat.
	$compter = mysql_query("SELECT COUNT(*) AS nbre_entrees FROM categories_annuaire WHERE id_categorie_mere = '$id_categorie_mere' ") or die(mysql_error()); 

	$nb_sous_categories = array_pop(mysql_fetch_row($compter));
					
	if ($nb_sous_categories != 0)
	   {					
		echo '<ul>';									
		while($categorie_mere{$niveau} = mysql_fetch_array($req_cat_mere{$niveau}))
		 {
		  $id_categorie_mere = $categorie_mere{$niveau} ['id'];
		  echo '<li>' .$categorie_mere{$niveau} ['nom_categorie']. '</li>';
		 }							
		$niveau = $niveau + 1;
	    }
 }			  
				  
 $nb_ul = 0;
 while($nb_ul != $niveau) // Je ferme autant de liste a puce que j'en ai ouvert
     {								
       echo '</ul>';
     }


Quelqu'un peut-il m'aider à débugger mon script

Merci d'avance.
Modifié par yann123 (29 May 2008 - 18:14)
Si tu ne sais pas à l'avance le nombre de niveaux, il te faudrait une fonction récursive. Le problème c'est que tu risque vite d'être confronté à une montée exponentielle des requêtes SQL et le temps d'exécution qui va avec... Si c'est vraiment trop long, penser à construire un arbre avec php mais avec une seule requête ou passer à une structure de représentation intervalaire, plus efficace pour les sélections mais plus coûteuse pour les insertions et suppressions.
Salut Yann Smiley cligne ,

tu pourrais essayer quelque chose comme ça :
<?php
function listeCategorie($id_categorie_mere) {
	$sql = "SELECT id, nom_categorie FROM categories_annuaire WHERE id_categorie_mere='$id_categorie_mere' order by nom_categorie";
	$result = mysql_query($sql) or die(mysql_error());
	if (mysql_num_rows($result) > 0) {
		echo '<ul>';
		while ($ligne = mysql_fetch_array($result)) {
			 echo '<li>'.$ligne['nom_categorie'];
			 listeCategorie($ligne['id']);
			 echo '</li>'."\n";
		}
		echo '</ul>';
	}
}

require_once('connexion.php');
listeCategorie(0);
?>

A+


Edit: au passage, ton imbrication actuelle n'est pas valide. Il faut avoir par exemple :
<ul>
     <li>cat 1</li>
     <li>cat 2</li>
     <li>cat 3
             <ul>
                     <li>cat 3_1</li>
              </ul>
     </li>
</ul>
ou pour dire ça autrement, un <ul> ne peut pas contenir directement un autre <ul> Smiley langue !
Modifié par Heyoan (29 May 2008 - 22:50)
Il me semble qu'il y a d'abord un choix entre deux solutions différentes, la première c'est le cas ou tu sélectionnes seulement une partie de ton arborescence, dans ce cas il est préférable d'utiliser une solution dans le style de celle d'Heyoan c'est a dire des sélect récursif mais en sélectionnant à chaque boucles pour voir si l'élément est parent ou soeur de la catégorie en cours.

Maintenant si tu veux afficher toute ton arborescence il est peut-être moins couteux en requête mysql de tout sélectionner en une requête (sans WHERE) est de construire l'arborescence en php.
Bonjour et merci de vos réponses.

La solution proposé par Heyoan fonctionne très bien, je n'avais pas encore utilisé de fonction récursive et cela ma permis de comprendre le principe. Smiley cligne

a écrit :
Maintenant si tu veux afficher toute ton arborescence il est peut-être moins couteux en requête mysql de tout sélectionner en une requête (sans WHERE) est de construire l'arborescence en php.


Désolé, je ne vois pas trop ce que tu veux dire matmat, comment je pourrais organiser le tableau du résultat de ma requête pour pouvoir afficher tout cela correctement.

Si vous pouvez me donner un peu plus de détails, pour que je fasse un choix. Smiley confused

Je reviens sur la solution de Heyoan dont j'ai compris le principe.

j'essaie de faire a peu prés la même fonction recursive afin de pouvoir choisir une catégorie dans une liste déroulante, car pour l'instant j'ai le même problème que dans mon premier message, mon script se répète et je suis limité a deux niveaux.

Je voudrais que ça s'affiche comme cela:

Categorie_mere >>> sous-categorie >>>Sous_categorie_niveau2

Donc il faut que je transmette le nom de la catégorie à chaque récursivité et que j'efface tout quand je repars d'une nouvelle catégorie mere.

J'ai ajouté une variable $debut à ma fonction qui est vide au premier appel de la fonction et a laquelle j'ajoute le nom du la catégorie ou sous-catégorie à chaque récursivité de la fonction.

Je n'arrive par contre pas a tous remettre a zero quand je change de categorie mére, j'ai essayé de mettre ma remise a zero dans plusieurs endroit, mais à chaque fois soit j'ai un nom en trop soit il me manque le debut.

Voici un exemple de ce que j'ai fais mais qui ne fonctionne pas:


<?php
include("include/fonctions-commune.php");  // Inclusion des fonctions général.				
				
function liste_categorie_formulaire($id_categorie_mere,$debut)
{
	$sql = "SELECT nom_categorie, id FROM categories_annuaire WHERE id_categorie_mere='$id_categorie_mere' ORDER BY nom_categorie";
	$requete_categorie = mysql_query($sql) or die(mysql_error());
	
		if (mysql_num_rows($requete_categorie) > 0)
		{						
		
			while ($categorie = mysql_fetch_array($requete_categorie) )
			{	 
			  echo '<option value="'.$categorie['id'].'">'. $debut . '>>>' . $categorie['nom_categorie'] .'</option>'."\n";
			   
			  $debut = $debut . '>>>' . $categorie['nom_categorie'];			      
					   
			  liste_categorie_formulaire($categorie['id'], $debut);	  	   			   			   			   
			  
			 }
			 	 	 
		}
		
		else // S'il n'y a plus de sous cat je remet le nom a zero.
		{
		   $debut = '';
		}
}
?>

<label for="id_categorie">Categorie du site:</label>
<select name="id_categorie" id="id_categorie" tabindex="05">
<option value="">Choisissez</option>

	<?php
	connexion('xxxxxxxx');	
	liste_categorie_formulaire(0,'');
	mysql_close(); // Déconnexion de MySQL
	?>
	
</select><br />


Encore merci pour votre aide.
C'est bon, j'ai résolu mon pb de cette maniére


<?php
include("include/fonctions-commune.php");  // Inclusion des fonctions général.				
				
function liste_categorie_formulaire($id_categorie_mere,$debut)
{
	$sql = "SELECT nom_categorie, id, id_categorie_mere FROM categories_annuaire WHERE id_categorie_mere='$id_categorie_mere' ORDER BY nom_categorie";
	$requete_categorie = mysql_query($sql) or die(mysql_error());
	
		if (mysql_num_rows($requete_categorie) > 0)
		{		
			while ($categorie = mysql_fetch_array($requete_categorie) )
			{	 
				  if ($categorie['id_categorie_mere'] == 0)
				  {
				   $debut = '';
				  }			  
			  
			  echo '<option value="'.$categorie['id'].'">'. $debut . '>>>' . $categorie['nom_categorie'] .'</option>'."\n";
			   
			  $debut = $debut . '>>>' . $categorie['nom_categorie'];			      
					   
			  liste_categorie_formulaire($categorie['id'], $debut);	  	   			   			   			   
			  
			 }
			 	 	 
		}
		
}
?>

<label for="id_categorie">Categorie du site:</label>
<select name="id_categorie" id="id_categorie" tabindex="05">
<option value="">Choisissez</option>

	<?php
	connexion('lxxxxxx');	
	liste_categorie_formulaire(0,'');
	mysql_close(); // Déconnexion de MySQL
	?>
	
</select><br />


Reste plus que la solution de matmat que j'aimerais comprendre Smiley cligne
Re-salut,

cela pourrait donner quelque chose comme ça (1 seule requête et alimentation d'un tableau) :
<?php
function listeCategorie($id_categorie_mere) {
	global $cat;
	if (count($cat[$id_categorie_mere]) > 0) {
		echo '<ul>'."\n";
		foreach ($cat[$id_categorie_mere] as $id => $nom_categorie) {
			 echo '<li>'.$nom_categorie;
			 listeCategorie($id);
			 echo '</li>'."\n";
		}
		echo '</ul>'."\n";
	}
}

require_once('../connexion.php');
$cat = array();
$sql = "SELECT id_categorie_mere, id, nom_categorie FROM categories_annuaire order by id_categorie_mere, nom_categorie";
$result = mysql_query($sql) or die(mysql_error());
if (mysql_num_rows($result) > 0) {
	while ($ligne = mysql_fetch_array($result)) {
		$cat[$ligne['id_categorie_mere']][$ligne['id']] = $ligne['nom_categorie'];
	}
	listeCategorie(0);
}
?>

A+ Smiley smile
Modifié par Heyoan (01 Jun 2008 - 17:17)