importer BDD dans un tableau HTML avec rowspans

Petit nouveau ! | 7 Messages

07 juil. 2015, 09:59

Bonjour et désolé pour le titre j'ai essayé de faire au plus court et le plus explicite possible avec la limite donnée.

Quelques lignes pour planter le décor :

Je suis débutant en PHP et je dois réaliser une petit application qui récupère les données d'une BDD et les affiche dans un tableau HTML. L'utilisateur par la suite sélectionne les données qui l’intéressent depuis le tableau et pour les rapatrier dans un fichier Excel.

Pour l'instant j'ai rapatrié ces données dans un tableau de façon assez brute :
<?php

	//connexion à la BDD avec PDO
	

	function Import()
	{
		global $bdd;

		$reponse = $bdd->query('SELECT * FROM Users');
		while ($donnees = $reponse->fetch())
		{
			echo '<tr> <td><input type="checkbox" name="choix" value="1"></td> <td>'.$donnees['Id'].'</td> <td>'.$donnees['Nom'].'</td> <td>'.$donnees['Prenom'].'</td> <td>'.$donnees['Type'].'</td> </tr>';
		}
		$reponse->closeCursor();
	}
?>
Voila pour la présentation.

Maintenant ma question :

Comme plusieurs données peuvent avoir des élément similaire, je souhaiterai avoir un rowpsan automatique sur certain champs : Image

Mais je ne vois pas du tout comment je peux mettre en place un rowspan en créant un tableau automatiquement.

Si quelqu'un pourrait m'éclairer, ce serait vraiment gentil.


PS : Je ne sais pas qu'elle est la bonne méthode pour la création d'un tableau en PHP, faut-il passer par un array et afficher cet array dans le tableau ou passer par une classe faire une liste d'objet issu de cet classe et afficher cette liste dans le tableau ou alors la méthode brute (celle utilisée) peut convenir?

Merci.

Mammouth du PHP | 688 Messages

07 juil. 2015, 10:11

trier la requete sql
faire une première boucle while ($donnees = $reponse->fetch()) pour recopier les données dans un tableau
prendre la première valeur, recuper le nombre de fois où ce modèle apparait, pour le rowspan
ajouter les lignes
recommencer quand le modele change

Petit nouveau ! | 7 Messages

07 juil. 2015, 10:42

Merci pour votre réponse !

Je pense avoir compris le principe dans l'ensemble mais ce n'est pas très clair :
trier la requete sql
Qu'entendez-vous par trier la requête SQL? Les classer avec un "ORDER BY" en fonction des champs qui subiront le rowspan pour les regrouper?
Faire une première boucle while ($donnees = $reponse->fetch()) pour recopier les données dans un tableau
prendre la première valeur, recuper le nombre de fois où ce modèle apparait, pour le rowspan
Quand vous dites de recopier les données dans un tableau, vous parlez d'un tableau HTML ou d'un tableau array?
Car si je recopie les lignes dans l'array, à chaque tour de boucle je vais perdre la ligne ?

Merci

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

07 juil. 2015, 17:07

Bonjour,

La difficulté de ce que tu veux faire, c'est que les tableaux html se construisent ligne par ligne et les rowspan doivent être spécifiés sur la première des lignes. Le problème de parcourir directement les enregistrements retournés par ta requête est que tu ne sais pas ce que contiendra l'enregistrement suivant et tu ne sauras donc pas si certaines données sont identiques à celles que tu est en train d'afficher.

Pour palier à cela il te faut effectivement stocker le résultat de ta requête dans un array php avant de commencer à l'afficher. Si ton tableau est bien construit (en l'occurrence, on est plus sur un arbre que sur un tableau en php et du coup ça devrait déjà ressembler à ce que tu veux obtenir à l'affichage), tu pourras ainsi savoir à l'avance combien d'enregistrements tu vas trouver en faisant des boucles et des count() réguliers.

Tu peux ainsi boucler sur chaque Marque, compter le nombre de modèle, puis compter le nombre de couleur par modèle, pour savoir combien de lignes devront être affichées pour cette marque et ainsi créer un TR et alimenter le rowspan. Puis pour chaque modèle compter le nombre de couleur et alimenter le rowspan, etc.
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Petit nouveau ! | 7 Messages

08 juil. 2015, 10:15

Bonjour et merci à vous deux pour vos réponses.

Je viens de regarder ce que sont les arbres et je crois que c'est ce que j'ai fait : Si j'ai bien compris un arbre est un array qui comporte d'autre array ? Dans mon cas l'array qui contient toutes les voitures serait l'arbre et les voitures individuellement seraient les branches ?

Si j'ai bien compris vos indications, il faudrait que je stock toute ma table dans un tableau mais la table que je veux importer comporte plus de 4000 lignes. Cela ne posera -t-il pas un problème au niveau de la mémoire si je dois tout mettre dans un seul tableau?

J'en suis arriver à ce code (qui fonctionne), où je met toutes les voitures de la même marque dans un tableau "tampon" que j’insère ensuite dans mon tableau HTML, le tableau est ensuite écrasé par les voitures de la marque suivante. Par contre je ne sais pas du tout si c’est fait proprement donc si vous pouvez éventuellement y jeter un oeil et éventuellement me donner un retour ou un point à améliorer / changer, ce serait vraiment gentil = :priere: O:) .
function Import()
	{
		global $bdd;

		$reponse = $bdd->prepare('SELECT * FROM voitures ORDER BY marque'); //On classe les résultats en fonction de la marque pour faciliter leur exploitation dans les boucles
		$reponse->execute();//On lance la requéte
		
		$data[0]=NULL;//Déclaration de Data pour ne pas avoir les notices 
		while($donnees = $reponse->fetch())//Tant qu'on a des données qui arrive de la requéte
		{	
			//Test pour voir si c'est une nouvelle marque
			if($data[0][0] == $donnees[0])//C'est la même marque que la ligne précédente
			{	
				array_push($data,$donnees);//On met la nouvelle ligne à la fin du tableau
			}

			else//Si c'est une nouvelle marque
			{
				Insertion_tableau($data); //appel de la fonction Insertion_tableau définit plus bas
				$data = array($donnees); //On écrase data avec les données d'une nouvelle disso
			}
		}
		Insertion_tableau($data); //On fait une insertion aprés la boucle pour la dérniére marque du tableau
	}

	function Insertion_tableau(&$data)
	{
		if($data[0] != NULL)//Condition pour la 1ere ligne (sinon rajoute ligne vide au début du tableau)
		{				
			$height = count($data); //On prend le nombre d'enregistrements dans data(qui representent le nb de voiture d'une même marque) pour calculer le rowspan
			if($height==1) // Si il y a une seule ligne
			{
				echo '<tr> <td><input type="checkbox" name="choix" value="1"></td> <td>'.$data[0][0].'</td> <td>'.$data[0][1].'</td> <td>'.$data[0][2].'</td> <td>'.$data[0][3].'</td> </tr>'; //On ne met pas de rowspan s'il ya une seule ligne	
			}
			else //Si il y a plusieurs lignes
			{
				echo '<tr> <td rowspan="'.$height.'"><input type="checkbox" name="choix" value="1"></td> <td rowspan="'.$height.'">'.$data[0][0].'</td> <td rowspan="'.$height.'">'.$data[0][1].'</td> <td>'.$data[0][2].'</td> <td>'.$data[0][3].'</td> </tr>'; //On place le rowpsan sur la 1ere ligne
		
				for($i=1 ; $i<$height ; $i++) // On commence à 1 car la 1ere ligne a déjà été placé
				{
					echo '<tr> <td>'.$data[$i][2].'</td> <td>'.$data[$i][3].'</td> </tr>';
				}
			}
		}	
	}
C'est peut-être un peu lourd mais je ne vois pas comment faire autrement, donc si vous avez des indications ;) ou si jamais ça peut servir à quelqu'un.

Merci pour votre aide!