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

Langage PHP Discussion :

Explode : récupérer valeurs champs suite requête


Sujet :

Langage PHP

  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut Explode : récupérer valeurs champs suite requête
    Bonjour,

    Ma question étant une question de débutant, je me permets de poster ici le message que j'ai posté hier sur le forum PHP & MYSQL. Il a peut-être plus sa place sur le forum débuter (les modérateurs peuvent s'ils le souhaitent supprimer mon message du forum PHP & MYSQL).

    J'ai une base de données MYSQL qui répertorie mes livres et qui comporte plusieurs tables dont les suivantes :
    - 1 table LIVRE comportant notamment comme champs : ID_LIVRE et TITRE
    - 1 table CATEGORIE comportant comme champs : ID_CATEGORIE et NOM_CATEGORIE (c-a-d roman, document, essais etc)
    - 1 table CLASSIFIE comportant comme champs : ID_LIVRE et ID_CATEGORIE
    - 1 table GENRE comportant comme champs : ID_GENRE et NOM_GENRE (c-a-d thriller, polar, SF etc)
    - 1 table THEMATISE comportant comme champs : ID_LIVRE et ID_GENRE

    Pour avoir des lignes de résultat du style,

    titre categories genres
    -------------------------------------------------------------------
    Titre 1 Categorie 2|Categorie 4 Genre 1|Genre 3

    j'utilise dans ma requête GROUP_CONCAT :
    Code : 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
    <?php
     
    try
    {
     
    	$bdd = new PDO('mysql:host=localhost;dbname=bibliosql', 'root', '');
     
    }
    catch(Exception $e)
    {
     
            die('Erreur : '.$e->getMessage());
    }
     
    	$reponse = $bdd->query('SELECT L.TITRE AS titre,
        GROUP_CONCAT(DISTINCT C.NOM_CATEGORIE SEPARATOR '|') AS categories,
        GROUP_CONCAT(DISTINCT G.NOM_GENRE SEPARATOR '|') AS genres
    FROM LIVRE L
    INNER JOIN CLASSIFIE A
        ON A.ID_LIVRE = L.ID_LIVRE
    INNER JOIN CATEGORIE C 
        ON A.ID_CATEGORIE = C.ID_CATEGORIE
    INNER JOIN THEMATISE T
        ON T.ID_LIVRE=L.ID_LIVRE
    INNER JOIN GENRE G
        ON G.ID_GENRE = T.ID_GENRE
    GROUP BY L.id_livre
    ORDER BY L.TITRE
    LIMIT 0,500');
    Voilà pour la partie SQL. Je coince sur la partie gestion de l'affichage en PHP.
    1) Comment récupérer les différentes valeurs du champ TITRE ? Grâce à foreach ? Mais je ne sais pas comment m'y prendre.
    2) Concernant la récupération des différentes valeurs sur les champs NOM_CATEGORIE et NOM_GENRE, je crois qu'il faut utiliser explode et foreach ? Ici non plus, je ne sais pas comment m'y prendre.
    Je précise que je suis un débutant n'ayant aucune pratique. Pouvez-vous m'aider à écrire le code permettant de gérer l'affichage souhaité ? Merci d'avance.

  2. #2
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Bonjour, il faut que tu fasses ceci :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    foreach($reponse as $row)
         echo $row['titre'];

    Tu peux également faire quelque chose comme ceci :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $reponse = $bdd->query('SELECT...', PDO::FETCH_OBJ);
     
    foreach($reponse as $row)
         echo $row->titre;

  3. #3
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    Merci Madfrix. Pour afficher le titre de mes livres, j'ai donc fait ce code :
    Code : 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
    <?php
     
    try
    {
     
    	$bdd = new PDO('mysql:host=localhost;dbname=bibliosql', 'root', '');
     
    }
    catch(Exception $e)
    {
     
            die('Erreur : '.$e->getMessage());
    }
     
    	$reponse = $bdd->query('SELECT L.TITRE AS titre
    	
    	from livre L
    LIMIT 0,500'); 
     
     
     foreach($reponse as $row)
         echo '<br/>'.$row['titre'].'<br/>';;
     
     
     ?>
    Effectivement mes titres sont listés. Mais pour afficher le(s) genres et catégorie(s) rattachés à ces titres, je dois faire , je crois, la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SELECT L.TITRE AS titre,
        GROUP_CONCAT(DISTINCT C.NOM_CATEGORIE SEPARATOR '|') AS categories,
        GROUP_CONCAT(DISTINCT G.NOM_GENRE SEPARATOR '|') AS genres
    FROM LIVRE L
    INNER JOIN CLASSIFIE A
        ON A.ID_LIVRE = L.ID_LIVRE
    INNER JOIN CATEGORIE C 
        ON A.ID_CATEGORIE = C.ID_CATEGORIE
    INNER JOIN THEMATISE T
        ON T.ID_LIVRE=L.ID_LIVRE
    INNER JOIN GENRE G
        ON G.ID_GENRE = T.ID_GENRE
    GROUP BY L.id_livre
    ORDER BY L.TITRE
    LIMIT 0,500
    Si j'essaye d'afficher la page avec cette requête au sein du code précédent, j'ai une erreur : "Warning: Invalid argument supplied for foreach()"
    C'est là je suppose qu'il faut prévoir l'explode pour gérer l'affichage des genres et catégories séparés par des "|" si un titre possède plusieurs genres ou catégories. Pouvez-vous de nouveau m'aider concernant cette fois-ci l'explode et le foreach associé ? Merci d'avance.

  4. #4
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Citation Envoyé par almoha Voir le message
    Si j'essaye d'afficher la page avec cette requête au sein du code précédent, j'ai une erreur : "Warning: Invalid argument supplied for foreach()"

    Alors tu as probablement une erreur dans ta requête elle-même. L'as tu testé sous phpMyAdmin par exemple ?

    Une fois quelle sera valide, tu pourras récupérer tes categories et tes genres via un explode dans ton foreach en effet :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $tab_categories = explode('|', $row['categories']);
    $tab_genres = explode('|', $row['genres']);

  5. #5
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    Ma requête fonctionnait avec phpMyAdmin mais pas avec PHP. J'ai trouvé la raison : le caractère séparateur | devait être entouré de " " et non de ' '.
    Ma requête est dorénavant valide mais je n'arrive pas à intégrer ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $tab_categories = explode('|', $row['categories']);
    $tab_genres = explode('|', $row['genres']);
    dans mon code après la requête, au niveau du foreach :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach($reponse as $row)
     
         echo '<br/>'.$row['titre'].'<br/>';
    pour récupérer les categories et tes genres par un echo via le explode.

    Merci d'avance de ton aide complémentaire.

  6. #6
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Il suffit juste de faire ceci :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    $tab_categories = array();
    $tab_genres = array();
     
    foreach($reponse as $row){
          $titre = $row['titre'];
          $tab_categories = explode('|', $row['categories']);
          $tab_genres = explode('|', $row['genres']);
    }

    Ainsi pour chaque ligne retournée ($row) tu as la liste des categories ans le tableau $tab_categories et la liste des genres dans le tableau $tab_genres

  7. #7
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    Merci de nouveau. Le code s'établit donc ainsi :
    Code : 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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    <?php
     
    try
    {
     
    	$bdd = new PDO('mysql:host=localhost;dbname=bibliosql', 'root', '');
     
    }
    catch(Exception $e)
    {
     
            die('Erreur : '.$e->getMessage());
    }
     
    	$reponse = $bdd->query('SELECT L.TITRE AS titre,
    	GROUP_CONCAT( DISTINCT C.NOM_CATEGORIE SEPARATOR "|" ) AS categories, 
    	GROUP_CONCAT( DISTINCT G.NOM_GENRE SEPARATOR "|" ) AS genres
    FROM LIVRE L
    INNER JOIN CLASSIFIE3 A ON A.ID_LIVRE = L.ID_LIVRE
    INNER JOIN CATEGORIE C ON A.ID_CATEGORIE = C.ID_CATEGORIE
    INNER JOIN THEMATISE T ON T.ID_LIVRE = L.ID_LIVRE
    INNER JOIN GENRE G ON G.ID_GENRE = T.ID_GENRE
    GROUP BY L.id_livre
    ORDER BY L.TITRE
    LIMIT 0 , 500
    ');
     
     
     
    $tab_categories = array();
    $tab_genres = array();
     
    foreach($reponse as $row){
          $titre = $row['titre'];
          $tab_categories = explode('|', $row['categories']);
          $tab_genres = explode('|', $row['genres']);
     
    	  echo '<br/>'.$row['titre'].'<br/>';
    	  echo '<br/>'.$row['categories'].'<br/>';
    	  echo '<br/>'.$row['genres'].'<br/>';
    }
    Reste une chose qui me chiffonne. L'affichage est du style :

    40 Récits curieux et édifiants de notre histoire

    Documents

    Histoire

    Béru contre San-Antonio

    Romans

    Policier|Humour

    Le livre "Béru contre San-Antonio" appartient à 2 genres différents : Policier d'une part et Humour d'autre part. L'affichage obtenu : Policier|Humour m'étonne. Je pensais qu'en l'espèce, grâce à l'explode, l'affichage aurait été :

    Béru contre San-Antonio

    Romans

    Policier
    Humour

    Quelque chose m'échappe-t-t-il encore ? Le fait que le caractère séparateur | figure toujours à l'affichage m'étonne. Merci d'avance de toute aide complémentaire.

  8. #8
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Bonsoir,

    c'est tout à fait logique, tu crées une variable mais tu l'utilises pas

    C'est encore plus simple que ca :

    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
     
    $tab_categories = array();
    $tab_genres = array();
     
    foreach($reponse as $row){
          $titre = $row['titre'];
          $tab_categories = explode('|', $row['categories']);
          $tab_genres = explode('|', $row['genres']);
     
          // affichage du titre
          echo '<br/>'.$titre.'<br/>';
     
          // affichage des catégories
          echo '<br/>';
          foreach($tab_categories as $categorie)
    	   echo $categorie .' ';
          echo '<br/>';
     
          // affichage des genre
          echo '<br/>';
          foreach($tab_genres as $genre)
    	   echo $genre.' ';
          echo '<br/>';
    }

  9. #9
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    Merci beaucoup pour l'ensemble de ton aide J'ai transposé le code pour afficher- en plus du titre, de la catégorie et du genre- le nom du ou des lecteur(s) et du ou des auteur(s) :
    Code : 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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    <?php
     
    try
    {
     
    	$bdd = new PDO('mysql:host=localhost;dbname=bibliosql', 'root', '');
     
    }
    catch(Exception $e)
    {
     
            die('Erreur : '.$e->getMessage());
    }
     
    	$reponse = $bdd->query('SELECT L.TITRE AS titre,
    				GROUP_CONCAT(DISTINCT C.NOM_CATEGORIE SEPARATOR "|") AS categories,
    				GROUP_CONCAT(DISTINCT G.NOM_GENRE SEPARATOR "|") AS genres,
    				GROUP_CONCAT(DISTINCT R.NOM_LECTEUR SEPARATOR "|") AS lecteurs,
    				GROUP_CONCAT(DISTINCT CB.NOM_CONTRIBUTEUR SEPARATOR "|") AS contributeurs
    				FROM LIVRE L
    				INNER JOIN CLASSIFIE3 A
    					ON A.ID_LIVRE = L.ID_LIVRE
    				INNER JOIN CATEGORIE C 
    					ON A.ID_CATEGORIE = C.ID_CATEGORIE
    				INNER JOIN THEMATISE T
    					ON T.ID_LIVRE = L.ID_LIVRE
    				INNER JOIN GENRE G
    					ON G.ID_GENRE = T.ID_GENRE
    				INNER JOIN LIT
    					ON LIT.ID_LIVRE = L.ID_LIVRE
    				INNER JOIN LECTEUR R
    					ON R.ID_LECTEUR = LIT.ID_LECTEUR
    				INNER JOIN ECRIT E
    					ON E.ID_LIVRE = L.ID_LIVRE	
    				INNER JOIN CONTRIBUTEURS CB
    					ON CB.ID_CONTRIBUTEUR = E.ID_CONTRIBUTEUR
    				GROUP BY L.id_livre
    				ORDER BY L.TITRE
    				LIMIT 0,500');
     
     
     
    $tab_categories = array();
    $tab_genres = array();
    $tab_lecteurs = array();
    $tab_contributeurs = array();
     
    foreach($reponse as $row){
          $titre = $row['titre'];
          $tab_categories = explode('|', $row['categories']);
          $tab_genres = explode('|', $row['genres']);
    	  $tab_lecteurs = explode('|', $row['lecteurs']);
    	  $tab_contributeurs = explode('|', $row['contributeurs']);
     
    	  // affichage du titre
          echo '<br/>'.$titre.'<br/>';
     
          // affichage des catégories
     
          foreach($tab_categories as $categorie)
    	   echo '<strong>'.$categorie.'</strong><br/>';
     
     
          // affichage des genres
     
          foreach($tab_genres as $genre)
    	   echo '<em>'.$genre.'</em><br/>';
     
    	   // affichage des lecteurs : MA TRANSPOSITION.
     
          foreach($tab_lecteurs as $lecteur)
    	   echo $lecteur.'<br/>';
     
    	  // affichage des contributeurs : MA TRANSPOSITION. 
     
          foreach($tab_contributeurs as $contributeur)
    	   echo $contributeur.'<br/>'; 
     
    }
     
     
     ?>
    L'affichage est conforme à mes attentes. Mais est-ce normal que la page PHP mette près de 8 secondes à s'afficher ? Je précise que ce temps d'affichage ne varie pas si je "réduit" le LIMIT. Est-ce dû à la multiplication des GROUP_CONCAT ? Par ailleurs, je constate la même lenteur en utilisant phpMyAdmin...
    As-tu une explication sur le sujet ? Merci d'avance.

  10. #10
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    C'est ta jointure qui fait probablement ramer (intérêt d'avoir autant de jointures ?)

    Pour calculer le temps d'exécution, tu peux faire ceci :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $debut = microtime(true);
    $reponse = $bdd->query(...);
    $fin= microtime(true);
     
    echo 'temps total : '.($fin-$debut);

  11. #11
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    J'ai calculé le temps d'exécution de ma page avec ton code : entre 6.90 et 7 secondes. Tu m'indiques que la cause est certainement le nombre de jointures effectuées. En pièce jointe, je fournis mon modèle de données pour que tu visualises toutes mes tables et leurs liens. Tu remarqueras que je suis obligé de passer par de nombreuses jointures pour afficher toutes les données. Ma requête actuelle devra être complétée afin de gérer en plus l'affichage des éditeurs (pas de GROUP_CONCAC nécessaire), des librairies où a été acheté le livre(idem), des formats (idem), des traducteurs, illustrateurs et préfaceurs (pour ces 3 types de contributeurs, un GROUP_CONCAC sera nécessaire, du moins pour les traducteurs). Le temps d'exécution de ma page risque de s'envoler...
    A noter que j'ai construit mon modèle de données avec l'aide d'un connaisseur en la matière. Existe-t-il un moyen d'optimiser ma requête finale pour obtenir un temps d'affichage correct ? Merci d'avance pour tout avis.

  12. #12
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Effectivement, ton modèle requiert beaucoup de jointures. A voir peut être du côté du forum SQL pour optimiser ta requête notamment au niveau de tes agrégations GROUP_CONCAT

    Au niveau PHP tu pourras rien gagner de plus à priori

  13. #13
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    Merci pour tout. Je vais poster un message sur le forum MYSQL pour l'optimisation de ma requête.

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

Discussions similaires

  1. [MySQL] Explode : récupérer valeurs champs suite requête
    Par almoha dans le forum PHP & Base de données
    Réponses: 0
    Dernier message: 30/07/2010, 22h48
  2. Récupérer un champs suite à une requête
    Par biddal dans le forum Requêtes
    Réponses: 9
    Dernier message: 21/02/2008, 15h46
  3. récupérer valeur champ libre formulaire dans un état
    Par stagolee dans le forum VBA Access
    Réponses: 1
    Dernier message: 10/01/2008, 14h18
  4. Réponses: 3
    Dernier message: 06/06/2007, 20h47
  5. Récupérer valeur champs de formulaire dynamique
    Par antillejj dans le forum ASP
    Réponses: 1
    Dernier message: 22/12/2006, 08h17

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