IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Intercallage et affichage avec des données issues de plusieurs tables SQL [MySQL]


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 278
    Par défaut Intercallage et affichage avec des données issues de plusieurs tables SQL
    Bonjour,

    Me revoilà avec un problème d'affichage.

    Je précise qu'au niveau des insertions, les données s'insèrent avec les bons identifiants.

    J'ai 4 tables : cours, chapitres, reponses, questions et une table relationnelle qui permet de faire les relations entre les 4 tables.

    Sur la page d'affichage, toutes les données s'affichent mais je rencontre un problème pour l'affichage des questions/exercices. Les questions/exercices dépendent des chapitres. Les questions/exercice prennent en compte l'identifiant du cours mais pas l'identifiant du chapitre. Je précise qu'il y a une fonction javascript, qui crée un sommaire avec les balises de titres (de <h1> jusqu'à <h7>) avec une numérotation automatique.

    J'ai essayé plusieurs fois, j'ai obtenu des résultats différents (affichage du bloc : "Exercices" dans chaque chapitre, etc…).

    Voici mon raisonnement :
    Pour chaque chapitre trouvé, tu vas voir dans la table des questions s'il y en a avec l'identifiant du chapitre : si oui, tu affiches le bloc : "Exercice" sinon tu passes au prochain chapitre (ainsi de suite pour chaque chapitre trouvé).

    Voici les requêtes SQL :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // Sélectionnement de l'identifiant de l'élève connecté
    $selection_identifiant_id_eleve_connecte = mysql_query("SELECT id_utilisateur FROM test_site_utilisateur WHERE id_utilisateur=".$_SESSION['id_utilisateur']." AND (acces_utilisateur='1' OR acces_utilisateur='5')") or die ('Erreur lors de la requête SQL qui permet de sélectionner l\'élève connecté.');
    // Sélectionnement du bon Cours/TP
    $selection_cours_tp = mysql_query("SELECT DISTINCT(t4.titre_chapitre),t2.titre_cours,t2.introduction_cours,t2.conclusion_cours,t2.date_publication_cours,t2.matiere_cours,t2.classe_cours,t4.contenu_chapitre, t2.id_cours FROM test_site_relation_cours_tp_utilisateur_v2 t1,test_site_cours_v2 t2,test_site_utilisateur t3,test_site_chapitres_v2 t4 WHERE t3.id_utilisateur=".$_SESSION['id_utilisateur']." AND t1.id_chapitre=t4.id_chapitre AND t1.id_cours=t2.id_cours AND (acces_utilisateur='1' OR acces_utilisateur='5') AND t2.id_cours='$id_cours_tp' AND t4.id_cours='$id_cours_tp'") or die("Erreur sur la requête SQL qui sélectionne toutes les informations du Cours/TP (sauf les questions et les réponses).");
    // Récupération des questions du Cours/TP dans la base de données - Deuxième version
    $query_selection_questions_cours_tp=mysql_query("SELECT DISTINCT(contenu_question) FROM test_site_questions_v2 t1, test_site_cours_v2 t2 WHERE t1.id_cours=t2.id_cours AND t2.id_cours='$id_cours_tp'") or die('Erreur lors de la sélection des questions d\'un Cours/TP'.mysql_error());

    Voici la partie du code actuel (où toutes les questions se mettent sous le premier chapitre alors qu'il y en a une qui doit se mettre sous le second chapitre) :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     $id_cours_tp = intval($_POST['id_cours_tp']);
    <?php
    if(mysql_num_rows($selection_identifiant_id_eleve_connecte)==1) {
          if(mysql_num_rows($query_selection_titre_cours_tp)==1) {
              echo "<header>".$_SESSION['titre_cours']."</header>";
          }
          echo '<div id="sommaire"></div>';
    		  if(mysql_num_rows($selection_cours_tp)>=1) {
    		  $classe_matiere=mysql_fetch_assoc($selection_classe_matiere);
    			  echo '<span class="informations_importantes">Classe : </span>'.html_entity_decode(stripslashes($classe_matiere['classe_cours']))."<br />";
                  echo '<span class="informations_importantes">Matière : </span>'.html_entity_decode(stripslashes($classe_matiere['matiere_cours']));
     
              while ($donnees_cours_tp_eleve = mysql_fetch_assoc($selection_cours_tp)) {
                  echo html_entity_decode(stripslashes($donnees_cours_tp_eleve['date_depot_cours']));
                  echo html_entity_decode(stripslashes($donnees_cours_tp_eleve['introduction_cours']));
                  echo "<h1>".html_entity_decode(stripslashes($donnees_cours_tp_eleve['titre_chapitre']))."</h1>";  
                  echo html_entity_decode(stripslashes($donnees_cours_tp_eleve['contenu_chapitre']));
    	            // Récupération du nombre d'enregistrements des questions du Cours/TP dans la base de données pour faire qu'un bloc "Exercices" s'il y a plusieurs questions (à voir avec une question par chapitre) - Deuxième version - Il faut améliorer pour que les questions s'affichent par rapport aux chapitres (au bon endroit)
                  $nombre_de_questions = mysql_num_rows($query_selection_questions_cours_tp);
                      // Boucle qui permet d'afficher la question et la zone de texte correspondante - DEBUT
                      for ($i = 0; $i < $nombre_de_questions; $i++) {
    	 $donnees_exercice_question_cours_tp_eleve = mysql_fetch_assoc($query_selection_questions_cours_tp);
                   if(mysql_num_rows($query_selection_questions_cours_tp)>=1) {               
    			echo '<div class="exercice">'.html_entity_decode(stripslashes($donnees_exercice_question_cours_tp_eleve['contenu_question'])).'<a name="question'.($i+1).'"></a><div class="reponse_cours_tp">Votre réponse <b>n°'.($i+1).'</b> <div style="position:relative; top:1.5em;left:0em;float:left;" id="image'.($i+1).'"></div>:<br /><textarea onkeyup="dynamicHeight(this);" rows="1" style="height: 40px;" cols="80" name="reponse'.($i+1).'" onChange="go('.($i+1).', this.value);"></textarea></div></div>';
    }
                      // Boucle qui permet d'afficher la question et la zone de texte correspondante - FIN
    	  	  }
            echo html_entity_decode($donnees_cours_tp_eleve['conclusion_cours']); 
    }
    }
    }
    ?>

    Ma question est : Comment afficher les questions et les zones de texte correspondantes (du bon cours) au bon endroit par rapport aux chapitres ? S'il n'y a pas de question, ce n'est pas la peine d'afficher le bloc : "Exercice". Actuellement, toutes les questions s'affichent sous le premier chapitre et ne prennent pas en compte le champs id_chapitre de la table des questions. De plus, le bloc "Exercice" s'affiche même quand il n'y a pas de question.

    Je viens vers vous en ayant réfléchi, je ne viens pas en "touriste" !

    Cordialement

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Une jointure entre deux tables s'écrit :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT champs FROM tableA
    JOIN tableB on tableA.champA = tableB.champB

    Ensuite en nommant tes alias t1, t2, t3 etc. il est evidemment impossible de s'y retrouver.

    Egalement on peut se demander ce que contient une table "site_relation_cours_tp_utilisateur".

    Bref, imaginons que tu aies bien une relation entre la table question et la table chapitre pour matérialiser que les questions font partie de chapitres.
    Si tu voulais afficher toutes les questions des chapitres 1 et 25 :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT champs FROM questions
    JOIN chapitre on questions.chapitre_id = chapitre.id
    WHERE chapitre.id IN (1,25)
    ORDER BY chapitre
    Il n'y a pas a faire deux requêtes.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 278
    Par défaut
    Merci de ta réponse.

    Juste pour information, voici les :

    Table des cours :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    CREATE TABLE IF NOT EXISTS `test_site_cours_v2` (
      `id_cours` int(11) NOT NULL AUTO_INCREMENT,
      `titre_cours` varchar(255) CHARACTER SET utf8 NOT NULL,
      `auteur_cours` varchar(255) CHARACTER SET utf8 NOT NULL,
      `introduction_cours` longtext CHARACTER SET utf8 NOT NULL,
      `conclusion_cours` longtext CHARACTER SET utf8 NOT NULL,
      `date_publication_cours` datetime NOT NULL,
      `date_cloture_validation_cours` datetime NOT NULL,
      `date_debut_validation_cours` datetime NOT NULL,
      `matiere_cours` varchar(255) CHARACTER SET utf8 NOT NULL,
      `classe_cours` varchar(255) CHARACTER SET utf8 NOT NULL,
      PRIMARY KEY (`id_cours`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=218 ;

    Table des chapitres :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE IF NOT EXISTS `test_site_chapitres_v2` (
      `id_chapitre` int(11) NOT NULL AUTO_INCREMENT,
      `id_cours` int(11) NOT NULL,
      `titre_chapitre` varchar(255) CHARACTER SET utf8 NOT NULL,
      `contenu_chapitre` longtext CHARACTER SET utf8 NOT NULL,
      `date_depot` datetime NOT NULL,
      `auteur_chapitre` varchar(255) CHARACTER SET utf8 NOT NULL,
      PRIMARY KEY (`id_chapitre`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=557 ;

    Table des questions :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE IF NOT EXISTS `test_site_questions_v2` (
      `id_question` int(11) NOT NULL AUTO_INCREMENT,
      `id_cours` int(11) NOT NULL,
      `id_chapitre` int(11) NOT NULL,
      `contenu_question` varchar(255) CHARACTER SET utf8 NOT NULL,
      `reponse_question` varchar(255) CHARACTER SET utf8 NOT NULL,
      `date_depot` datetime NOT NULL,
      `auteur_question` varchar(255) CHARACTER SET utf8 NOT NULL,
      PRIMARY KEY (`id_question`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2385 ;

    Table des réponses :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE IF NOT EXISTS `test_site_reponses_v2` (
      `id_reponse` int(11) NOT NULL AUTO_INCREMENT,
      `id_cours` int(11) NOT NULL,
      `id_chapitre` int(11) NOT NULL,
      `texte_reponse` longtext CHARACTER SET utf8 NOT NULL,
      `question_reference` varchar(255) CHARACTER SET utf8 NOT NULL,
      `date_depot` datetime NOT NULL,
      `auteur_reponse` varchar(255) CHARACTER SET utf8 NOT NULL,
      PRIMARY KEY (`id_reponse`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3109 ;

    Table relationnelle :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE IF NOT EXISTS `test_site_relation_cours_tp_utilisateur_v2` (
      `id_rel_cours_utilisateur_chapitre_question_reponse` int(11) NOT NULL AUTO_INCREMENT,
      `id_cours` int(11) NOT NULL,
      `id_utilisateur` int(11) NOT NULL,
      `id_chapitre` int(11) NOT NULL,
      `id_question` int(11) NOT NULL,
      `id_reponse` int(11) NOT NULL,
      `date_depot_rel_cours_user` datetime NOT NULL,
      PRIMARY KEY (`id_rel_cours_utilisateur_chapitre_question_reponse`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4159 ;

    Cordialement

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Dans un modèle relationnelle, ta "table relationnelle" n'existe pas.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 278
    Par défaut
    Bonjour,

    Comme tu me l'as soumis, j'ai remplacé les deux requêtes SQL par cette requête :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $query_selection_questions_cours_tp=mysql_query("SELECT titre_chapitre,contenu_chapitre,contenu_question
    FROM test_site_chapitres_v2
    JOIN test_site_questions_v2
    ON test_site_chapitres_v2.id_chapitre=test_site_questions_v2.id_chapitre
    AND test_site_chapitres_v2.id_cours = '$id_cours_tp'")
    or die('Erreur lors de la sélection des questions d\'un Cours/TP'.mysql_error()); // Envoie une requête à un serveur MySQL

    J'ai toujours cette requête SQL :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // Sélectionnement de l'identifiant de l'élève connecté
    $selection_identifiant_id_eleve_connecte = mysql_query("SELECT id_utilisateur
    FROM test_site_utilisateur
    WHERE id_utilisateur=".$_SESSION['id_utilisateur']."
    AND (acces_utilisateur='1' OR acces_utilisateur='5')")
    or die ('Erreur lors de la requête SQL qui permet de sélectionner l\'élève connecté.'); // Envoie une requête à un serveur MySQL

    Voici le bloc d'affichage :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
      <?php
      if(mysql_num_rows($selection_identifiant_id_eleve_connecte)==1) {
              echo "<header>".$_SESSION['titre_cours']."</header>";
          echo '<div id="sommaire"></div>';
              while ($donnees_cours_tp_eleve = mysql_fetch_assoc($query_selection_questions_cours_tp)) {
     
                  echo html_entity_decode(stripslashes($donnees_cours_tp_eleve['date_depot_cours']));
                  echo html_entity_decode(stripslashes($donnees_cours_tp_eleve['introduction_cours']));
                  echo "<h1>".html_entity_decode(stripslashes($donnees_cours_tp_eleve['titre_chapitre']))."</h1>";
     
                  echo html_entity_decode(stripslashes($donnees_cours_tp_eleve['contenu_chapitre']));
     
     
                  $nombre_de_questions = mysql_num_rows($query_selection_questions_cours_tp);
                      // Boucle qui permet d'afficher la question et la zone de texte correspondante - DEBUT
                      for ($i = 0; $i < $nombre_de_questions; $i++) {
    	 $donnees_exercice_question_cours_tp_eleve = mysql_fetch_assoc($query_selection_questions_cours_tp);
                   if(mysql_num_rows($query_selection_questions_cours_tp)>=1) {                  
     
    						echo '<div class="exercice">'.html_entity_decode(stripslashes($donnees_exercice_question_cours_tp_eleve['contenu_question'])).'<a name="question'.($i+1).'"></a><div class="reponse_cours_tp">Votre réponse <b>n°'.($i+1).'</b> <div style="position:relative; top:1.5em;left:0em;float:left;" id="image'.($i+1).'"></div>:<br /><textarea onkeyup="dynamicHeight(this);" rows="1" style="height: 40px;" cols="80" name="reponse'.($i+1).'" onChange="go('.($i+1).', this.value);"></textarea></div></div>';
    }               
                      // Boucle qui permet d'afficher la question et la zone de texte correspondante - FIN
    	  	  }
            echo html_entity_decode($donnees_cours_tp_eleve['conclusion_cours']); 
    }
     }      
    ?>

    Alors maintenant, tous les chapitres ne s'affichent plus. Si vous pouvez me faire un code qui permet d'afficher tout les chapitres avec les questions qui s'affichent au bon endroit, ce serait parfait.

  6. #6
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Première chose, écris ton code proprement en indentant bien.
    Exemple de ce qu'il ne faut pas avoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     $donnees_exercice_question_cours_tp_eleve = mysql_fetch_assoc($query_selection_questions_cours_tp);
                   if(mysql_num_rows($query_selection_questions_cours_tp)>=1) {                  
     
    						echo '<div class="exercice">'.html_entity_decode(stripslashes($donnees_exercice_question_cours_tp_eleve['contenu_question'])).'<a name="question'.($i+1).'"></a><div class="reponse_cours_tp">Votre réponse <b>n°'.($i+1).'</b> <div style="position:relative; top:1.5em;left:0em;float:left;" id="image'.($i+1).'"></div>:<br /><textarea onkeyup="dynamicHeight(this);" rows="1" style="height: 40px;" cols="80" name="reponse'.($i+1).'" onChange="go('.($i+1).', this.value);"></textarea></div></div>';
    }               
                      // Boucle qui permet d'afficher la question et la zone de texte correspondante - FIN
    	  	  }
    Ensuite html_entity_decode(stripslashes()) est à bannir : le HTML dans ta base de données ne doit ni contenir des entités HTML, ni des slashes en trop ; il n'y a donc pas besoin de les retirer/convertir en lecture.
    Donc si tu as un htmlentities() dans des requêtes d'insertion, enlève le. mysql_real_escape_string() est là pour echapper les données.

    Continuons ...
    Pour parcourir tous les résultats d'une requête on ne fait pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      for ($i = 0; $i < $nombre_de_questions; $i++) {
    	 $donnees_exercice_question_cours_tp_eleve = mysql_fetch_assoc($query_selection_questions_cours_tp);
    On fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     while ($row = mysql_fetch_assoc($query_questions);
    Tu remarqueras au passage que j'ai considérablement raccourci le nom de tes variables. On peut avoir des variables tout à fait explicite sur leur contenu et leur rôle sans écrire "$donnees_exercice_question_cours_tp_eleve". Au contraire tes variables a rallonge ne sont pas lisibles et rendent le code illisble.

    Pour finir, tu comptes deux fois le nombre de lignes (ligne 14 et ligne 18). Celui de la ligne 18 est doublement inutile : tu connais déjà le résultat et tu es déjà engagé dans une boucle pour afficher les lignes, il est donc un peu tard pour vérifier s'il y en a.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 11
    Dernier message: 18/10/2007, 12h49
  2. Réponses: 2
    Dernier message: 04/06/2007, 16h38
  3. Réponses: 2
    Dernier message: 21/02/2007, 11h22
  4. [MySQL] Remplir un array() avec des données issues d'une bdd
    Par fichtre! dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 18/12/2006, 17h03
  5. Réponses: 6
    Dernier message: 11/07/2006, 10h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo