Affichage données suite à 2 foreach

Eléphanteau du PHP | 47 Messages

13 août 2010, 18:29

Bonjour,

L'extrait de code suivant doit m'afficher l'identité des contributeurs d'un livre et le type de fonction exercée (auteur ou traducteur):
<?php
 
requête SQL...
 
$tab_contributeurs = array();
$tab_fonctions = array();
 
foreach($reponse as $row)
{
$titre = $row['titre'];
(...)
 
$tab_contributeurs = explode('|', $row['contributeurs']);
$tab_fonctions= explode('|', $row['nom_fonctions']);
 
 
// affichage des fonctions : auteur, traducteur
	   
	  foreach($tab_fonctions as $fonction)
	  
	   echo $fonction.' : <br/>'; 
	   
	   
	  // affichage des contributeurs : identité de l'auteur, traducteur
      
      foreach($tab_contributeurs as $contributeur)
				
	   echo $contributeur.'<br/>'; 
	   
}?>
Me donne l'affichage suivant :

traducteur :
auteur :
auteur1
auteur2
traducteur1
traducteur2

alors que je souhaite cet affichage :

auteurs : auteur1, auteur2 (...)
traducteurs : traducteur1, traducteur2 (...)

J'ai fait les var_dump (ex : Pour un livre ayant comme auteurs : E. Winter et Collectif et comme traducteur : Breque) :

- de $tab_fonctions :
array(2) { [0]=>  string(6) "auteur" [1]=>  string(10) "traducteur" } 
- de $tab_contributeurs :
array(3) { [0]=>  string(9) "E. Winter" [1]=>  string(6) "Breque" [2]=>  string(9) "Collectif" } 
L'affichage obtenu est :

auteur :
traducteur :
E. Winter
Breque
Collectif

Je vous donne la structure des tables concernées :

- 1 table FONCTION comportant comme champs : id_fonction et nom_fonction
- 1 table CONTRIBUTEURS comportant comme champs : id_contributeur, nom_contributeur, prenom_contributeur
- 1 table LIVRE comportant comme champs notamment : id_livre, titre ...
- 1 table PARTICIPE comportant comme champs : id_contributeur, id_fonction et id_livre

et ma requête :
$reponse = $bdd->query('SELECT L.TITRE AS titre, (...)
 
				GROUP_CONCAT(DISTINCT CB.NOM_CONTRIBUTEUR SEPARATOR "|") AS contributeurs,
				GROUP_CONCAT(DISTINCT F.NOM_FONCTION SEPARATOR "|") AS nom_fonctions
				
				FROM LIVRE L
				(...)
					
				INNER JOIN PARTICIPE P
					ON P.ID_LIVRE = L.ID_LIVRE	
				INNER JOIN CONTRIBUTEURS CB
					ON CB.ID_CONTRIBUTEUR = P.ID_CONTRIBUTEUR
					
				INNER JOIN FONCTION F
					ON F.ID_FONCTION = P.ID_FONCTION		
					
					
				GROUP BY L.id_livre
				ORDER BY L.TITRE
				LIMIT 0,100')
Pouvez-vous m'aider à obtenir l'affichage souhaité ? Merci d'avance.

ViPHP
ViPHP | 2291 Messages

13 août 2010, 18:44

Salut

Supprime le <br/>
ImageCe que l'on apprend par l'effort reste toujours ancré beaucoup plus longtemps.

Eléphanteau du PHP | 47 Messages

13 août 2010, 18:57

Si j'enlève à mon code les 2 <br/>, l'affichage devient :

auteur : traducteur : E. WinterBrequeCollectif

Ce qui malheureusement n'est pas l'affichage escompté :(
Merci pour toute aide complémentaire.

ViPHP
ViPHP | 2291 Messages

13 août 2010, 19:43

Salut,
echo 'Auteur : ';
          foreach($tab_fonctions as $fonction)

	           echo $fonction . ' ';
	           echo '<BR />';


          // affichage des contributeurs : identité de l'auteur, traducteur
          echo 'Contributeur : ';
          foreach($tab_contributeurs as $contributeur)

	           echo $contributeur . ' ';
	           echo '<BR />';




ImageCe que l'on apprend par l'effort reste toujours ancré beaucoup plus longtemps.

Eléphanteau du PHP | 47 Messages

13 août 2010, 20:44

Merci pour le code. Mais l'affichage obtenu est le suivant :

Auteur : auteur traducteur
Contributeur : E. Winter Collectif Brèque

Voyez-vous une autre façon d'arriver à l'affichage souhaité ? Merci d'avance.

ViPHP
ViPHP | 2291 Messages

13 août 2010, 20:51

Salut,

Sorry j'avais pas bien prie la peine de lire
Comme ceci cela devrait être correct.
// affichage des fonctions : auteur, traducteur

          foreach($tab_fonctions as $fonction){

	           echo $fonction . ' ';



          // affichage des contributeurs : identité de l'auteur, traducteur

          foreach($tab_contributeurs as $contributeur)

	           echo $contributeur . ' ';
	           echo '<BR />';
       }
ImageCe que l'on apprend par l'effort reste toujours ancré beaucoup plus longtemps.

Eléphanteau du PHP | 47 Messages

13 août 2010, 21:03

Je viens d'essayer le nouveau code mais l'affichage est le suivant :

auteur Collectif E. Winter Brèque
traducteur Collectif E. Winter Brèque

alors que je voudrais l'affichage suivant :

auteur : Collectif; E. Winter
traducteur : Brèque

Je me demande si mon code fait bien la relation entre $tab_fonctions et $tab_contributeurs ? A moins que ma requête soit incomplète ? Vois-tu une explication ? Merci encore.

Eléphanteau du PHP | 47 Messages

14 août 2010, 20:46

Bonjour,

J'ai beau me creuser la tête mais je n'arrive à obtenir l'affichage indiqué dans mes messages de hier. C'est frustrant :( Existe-t-il une solution ? Pardon de déjà relancer le sujet. Merci d'avance.

ViPHP
xTG
ViPHP | 7331 Messages

14 août 2010, 21:25

Pour ce que je comprends de ton problème c'est plus un soucis de structure de donnée que de manipulation de ces dites données.
Comment fais-tu la distinction dans ton array s'il y a deux auteurs et un traducteur ? Et inversement ?
On ne peut pas poser de retour à la ligne sans savoir où il faut le mettre. :)

Eléphanteau du PHP | 47 Messages

14 août 2010, 22:07

Merci de ta réponse xTG. A ton avis, le problème peut-il être lié à ma requête qui serait erronée ?
$reponse = $bdd->query('SELECT L.TITRE AS titre, (...)
 
                                GROUP_CONCAT(DISTINCT CB.NOM_CONTRIBUTEUR SEPARATOR "|") AS contributeurs,
                                GROUP_CONCAT(DISTINCT F.NOM_FONCTION SEPARATOR "|") AS nom_fonctions
                               
                                FROM LIVRE L
                                (...)
                                       
                                INNER JOIN PARTICIPE P
                                        ON P.ID_LIVRE = L.ID_LIVRE     
                                INNER JOIN CONTRIBUTEURS CB
                                        ON CB.ID_CONTRIBUTEUR = P.ID_CONTRIBUTEUR
                                       
                                INNER JOIN FONCTION F
                                        ON F.ID_FONCTION = P.ID_FONCTION               
                                       
                                       
                                GROUP BY L.id_livre
                                ORDER BY L.TITRE
                                LIMIT 0,100')
Ou la structure de mes tables n'est-elle pas cohérente ? Qu'en pensez-vous ? Merci d'avance.

ViPHP
xTG
ViPHP | 7331 Messages

14 août 2010, 23:07

Cela provient de ta façon d'enregistrer les données.
Tu ne fais aucune distinction entre auteurs et traducteurs, tu les classent tous dans contributeurs sans les différencier.
Utilises un séparateur pour indiquer la fin de la liste des auteurs et le début de celle des traducteurs.
Avec ce séparateur tu seras capable de savoir quand passer à la prochaine valeur de ton $tab_fonctions.

Eléphanteau du PHP | 47 Messages

14 août 2010, 23:20

Merci de ces précisions. J'espère ne pas abuser en te demandant d'expliciter ce que je dois entendre par utiliser un séparateur. Dois-je ajouter un champ dans ma table contributeur ?
De plus :
Avec ce séparateur tu seras capable de savoir quand passer à la prochaine valeur de ton $tab_fonctions.
Comment faire ceci concrètement dans mon code ? Je suis vraiment débutant... En espérant avoir de ta part des renseignements complémentaires. Merci beaucoup.

ViPHP
xTG
ViPHP | 7331 Messages

15 août 2010, 10:15

Au temps pour moi j'avais trop rapidement parcouru ta requête...
Tu as un enregistrement par contributeur si je ne m'abuse non ?
As-tu dans ta table contributeur un champ les différenciant ? (auteur, ect)

Eléphanteau du PHP | 47 Messages

15 août 2010, 10:58

Bonjour,

J'ai effectivement un enregistrement par contributeur. Mais ma table CONTRIBUTEURS ne contient que les champs suivants :

id_contributeur, nom_contributeur, prenom_contributeur

Je n'ai donc pas de champ différenciant les contributeurs selon leur fonction. Mais je pensais qu'avec mes 2 autres tables :

- table FONCTION comportant comme champs : id_fonction et nom_fonction
- table PARTICIPE comportant comme champs : id_contributeur, id_fonction et id_livre

j'étais à même d'effectuer cette différenciation grâce à la requête écrite. Mais ce n'est pas le cas car je n'arrive pas à l'affichage souhaité.

Merci de toute aide complémentaire :)

ViPHP
xTG
ViPHP | 7331 Messages

15 août 2010, 12:02

Ta structure de table est correcte donc pour résoudre le problème.
Il faut modifier la requête, je ne m'aventurerai cependant pas dedans moi même, j'ai très peu de connaissances SQL et je risquerai de faire une usine à gaz (pour exemple il ne m'est encore jamais arrivé de faire une aussi grosse requête que la tienne).

Mais dans l'esprit il te faut récupérer les id et les noms dans les deux groupes (fonction et contributeurs).
Ensuite boucler afin d'obtenir une structure de donnée de ce genre (par exemple) :
// fonctions
array( 'id_fonction' => 'nom_fonction', 'id_fonction2' => 'nom_fonction2');
// contributeurs
array( 0 => array( 'nom_contributeur', 'id_fonction'), 1 => array( 'nom_contributeur2', 'id_fonction2') )
Ensuite on peut traiter le second array pour l'affichage :
array( 'id_fonction' => array(... /* liste des noms des contributeurs de type id_fonction */), ...); 
Bien sûr on peut aussi construire directement l'array final dès la première boucle.
Après c'est tout simple :
foreach($mon_array_final as $id_fonction => $liste_contributeur)
{
  echo $mon_array_fonction[$id_fonction]; // Le nom de la fonction
  foreach($liste_contributeur as $nom)
    echo $nom; // Le nom du contributeur
  echo "<br />"; // On change de fonction donc retour à la ligne
}
En espérant que quelqu'un vienne à ton secours pour la requête. :)