8768 sujets

Développement web côté serveur, CMS

Pages :
Bonjour à tous,

Sur la dernière ligne droite de mon projet, je rencontre un ultime soucis depuis un moment maintenant.

Voici ma page :

upload/1493191571-64910-14931241652031sanstitre.png

Je récupère toutes ces infos depuis ma base de données. En violet, le spoiler qui s'affiche lorsque l'utilisateur clique sur "plus d'infos". Ces informations varient d'une ville à une autre.

Mon problème se situe ici : Je souhaite afficher toutes les dates précisément et leurs séances dans ce style la : Le 07 Juillet à 14h30, 17h00 et 20h30 pour cet exemple.

Sachant que dans ma base de données les événements et les séances sont dans 2 tables différentes reliées par id_event.

Ces séances sont au format datetime dans la base de données.

J'ai déjà fait des formatage dans cette page (Pour afficher les dates de début et de fin), voici mon code actuel :


<table class="tabletournee">
            <caption>Dates et lieux de la tournée 2017</caption>
             
                <?php
                try
                {
                    $bdd = new PDO('mysql:host=localhost;dbname=medrano2017;charset=utf8', 'root', '');
                    $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                }
                catch(Exception $e)
                {
                    die('Erreur : '.$e->getMessage());
                }
 
                    $reponse = $bdd->query('SELECT id_event,
                      id_tournee,
                      evenement.ville_event       AS ville,
                      evenement.lien_resa_event   AS lienresa,
                      evenement.adresse_event     AS adresse,
                      tournee.description_tournee AS descriptiontournee,
                      tournee.nom_tournee         AS nomtournee,
                      (SELECT MIN(s.dateheure_seance) FROM seance s WHERE s.id_event = evenement.id_event) AS premiereSeance,
                      (SELECT MAX(s.dateheure_seance) FROM seance s WHERE s.id_event = evenement.id_event) AS derniereSeance
                    FROM tournee
                    JOIN evenement USING(id_tournee)
                    ORDER BY premiereSeance,derniereSeance');
 
                    $compteur =0;
 
                    $datecourante = date('Y-m-d H:i:s');
 
                    while ($donnees = $reponse->fetch())
                    {
 
                    setlocale(LC_ALL, 'French', 'fr-FR.utf8','fra', 'fr-FR', 'fr_FR', 'fr', 'fr_FR@euro');
                    $datedebut = strftime("%d %B", strtotime($donnees['premiereSeance']));
                    $datefin = strftime("%d %B %Y", strtotime($donnees['derniereSeance']));
 
                    if( $donnees['derniereSeance'] >= $datecourante )
                    {
                ?>
                    <tr class="infotournee infotournee<?php echo ($compteur%2); $compteur++; ?>">
                        <td id="event<?php echo $donnees['id_event']; ?>"><p style="color:white;" class="villetournee"><?php echo ''.$donnees['ville'].'';?></p> <p class="nomtournee"><?php echo ''.$donnees['nomtournee'].'';?></p></td>
                        <td><?php echo (strpos($datedebut,' '.$datefin))? 'Le '.utf8_encode($datedebut) : 'Du '.utf8_encode($datedebut).'<br/>au '.utf8_encode($datefin); ?></td>
                        <td><?php echo ''.$donnees['adresse'].'';?></td>
                        <td><a href="#spoiler<?php echo $donnees['id_event']; ?>" class="spoiler-link lienresa">PLUS D'INFOS</a><a class="lienresa" href="#">RESERVER</a></td>
                    </tr>
                    <tr>
                        <td colspan="4">
                            <div class="spoilers">
                                <div class="spoiler" id="spoiler<?php echo $donnees['id_event']; ?>">
                                    <p><?php echo ''.utf8_encode($datedebut).'';?></p>
                                </div>
                            </div>
                        </td>
                    </tr>
                <?php
                    }
                    }
                        $reponse->closeCursor();
                ?>
        </table>


J'ai essayé de rajouter cette ligne dans ma requête :
(SELECT dateheure_seance FROM seance s WHERE s.id_event = evenement.id_event) AS Seances,


Mais ça me produit cette erreur :

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[21000]: Cardinality violation: 1242 Subquery returns more than 1 row' in C:\wamp\www\Medrano2017\index.php on line 78


(La ligne 78 correspond à la fin de ma requête)
Si vous avez la moindre idée, je suis vraiment preneur parce que je me casse la tête depuis un moment sans succès....
Merci d'avance !
Salut Smiley smile

C'est en soi une bonne idée de vouloir tout récupérer en une seule requète Smiley smile

Le problème c'est que comme le dit l'erreur tu as plus d'un seul résultat dans ta sous requète Smiley smile et ça bah sql le gère pas Smiley cligne

Donc ton process est bon mais il te faut une deuxième requète pour afficher les dates et heure Smiley cligne

Pendant ta boucle d'affichage des événements, tu lance cette deuxième requète spécialement pour les horaires sur l'id de l'événement, et là tu pourra compléter ton div Smiley smile

Simple en fait Smiley smile
Bonjour,

Alors déjà merci beaucoup, ça me rassure !!

Voila ce que j'ai fais :


$reponse1 = $bdd->query('SELECT dateheure_seance FROM seance s, evenement e WHERE s.id_event = e.id_event');
$donnees1 = $reponse1->fetch();


Je l’ai inséré dans ma boucle while, juste après mes formatage de dates.
Ensuite, dans le spoiler, j'ai pour l'instant affiché les résultats comme ça :
<p><?php echo var_dump($donnees1['dateheure_seance']); ?></p>


Or, le résultat est le même pour chaque spoiler... Et il n'affiche qu'une seule date :
C:\wamp\www\Medrano2017\index.php:86:string '2017-07-07 18:00:00' (length=19)


Or, voici le contenu de ma table seance :

upload/1493196205-64910-sanstitre.png

Si tu as une idée merci d'avance !
Modifié par I--Zop--I (26 Apr 2017 - 10:45)
Bonjour,

C'est lié à l'utilisation de la fonction fetch qui ne renvoie qu'une seule réponse.
Tu peux utiliser la fonction fecthall qui va te renvoyer un tableau avec tout les résultats.
Pour afficher, les résultats de ton tableau tu fais un foreach sur ce tableau.

En espèrent t'avoir aidé.
Bonjour,

D'accord, on avance petit à petit !
Cependant, je viens de me rendre compte d'une erreur : Le résultat de ma requête est maintenant le même pour tous les spoilers.

La voici :
SELECT dateheure_seance FROM seance s, evenement e WHERE s.id_event = e.id_event

Or, quand je veux ajouter id_event dans mon SELECT, ça me produit cette erreur :
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1052 Champ: 'id_event' dans field list est ambigu'
Ambigu car tu as 2 colonnes qui ont le même nom. Il faut préciser la table voulue comme tu le fais dans ta clause where avec ton alias.
Hum d'accord, j'ai fais cela du coup :
SELECT s.id_event, e.id_event, dateheure_seance AS seances FROM seance s, evenement e WHERE s.id_event = e.id_event


Par contre, les résultats sont tous les mêmes pour les spoilers.... Smiley bawling
Le voici :


<table class="tabletournee" id="myTable">
            
                <?php

                try
                {
                    $bdd = new PDO('mysql:host=localhost;dbname=medrano2017;charset=utf8', 'root', '');
                    $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                }
                catch(Exception $e)
                {
                    die('Erreur : '.$e->getMessage());
                }

                    $reponse = $bdd->query('SELECT id_event,
                      id_tournee,
                      evenement.ville_event       AS ville,
                      evenement.lien_resa_event   AS lienresa,
                      evenement.adresse_event     AS adresse,
                      tournee.description_tournee AS descriptiontournee,
                      tournee.nom_tournee         AS nomtournee,
                      (SELECT MIN(s.dateheure_seance) FROM seance s WHERE s.id_event = evenement.id_event) AS premiereSeance,
                      (SELECT MAX(s.dateheure_seance) FROM seance s WHERE s.id_event = evenement.id_event) AS derniereSeance
                    FROM tournee
                    JOIN evenement USING(id_tournee)
                    ORDER BY premiereSeance,derniereSeance');

                    $compteur =0;

                    $datecourante = date('Y-m-d H:i:s');

                    while ($donnees = $reponse->fetch())
                    {

                    setlocale(LC_ALL, 'French', 'fr-FR.utf8','fra', 'fr-FR', 'fr_FR', 'fr', 'fr_FR@euro');
                    $datedebut = strftime("%d %B", strtotime($donnees['premiereSeance']));
                    $datefin = strftime("%d %B %Y", strtotime($donnees['derniereSeance']));

                    $reponse1 = $bdd->query('SELECT s.id_event, e.id_event, dateheure_seance AS seances FROM seance s, evenement e WHERE s.id_event = e.id_event');
                    $donnees1 = $reponse1->fetchall();

                    if( $donnees['derniereSeance'] >= $datecourante )
                    {
                ?>
                    <tr class="infotournee infotournee<?php echo ($compteur%2); $compteur++; ?>">
                        <td id="event<?php echo $donnees['id_event']; ?>"><p style="color:white;" class="villetournee"><?php echo ''.$donnees['ville'].'';?></p> <p class="nomtournee"><?php echo ''.$donnees['nomtournee'].'';?></p></td>
                        <td><?php echo (strpos($datedebut,' '.$datefin))? 'Le '.utf8_encode($datedebut) : 'Du '.utf8_encode($datedebut).'<br/>au '.utf8_encode($datefin); ?></td>
                        <td><?php echo ''.$donnees['adresse'].'';?></td>
                        <td><a href="#spoiler<?php echo $donnees['id_event']; ?>" class="spoiler-link lienresa">PLUS D'INFOS</a><a class="lienresa" href="#">RESERVER</a></td>
                    </tr>
                    <tr>
                        <td colspan="4">
                            <div class="spoilers">
                                <div class="spoiler" id="spoiler<?php echo $donnees['id_event']; ?>">
                                    <p>
                                      <?php 
                                        /*foreach ($donnees1 as $dates) 
                                        {
                                          echo $dates;
                                        }*/
                                        var_dump($donnees1['seances']);
                                      ?>
                                    </p>
                                </div>
                            </div>
                        </td>
                    </tr>
                    
                <?php
                    }
                    }
                        $reponse->closeCursor();
                ?>
        </table>


La ça me dit que seances n'est pas défini dans le spoiler...

Et j'ai testé avec uniquement la methode fetch() pour voir, et ça me renvoi la première ligne de la table seance pour chaque spoiler.
ton tableau $donnees contient bien $donnees['id_event'] ?
si c'est la cas, vu que tu es déjà dans une boucle tu pourrais teneter de faire la requête suivante :

$reponse1 = $bdd->query("SELECT dateheure_seance AS seances FROM seance s WHERE s.id_event = '".$donnees['id_event']."')";
$donnees1 = $reponse1->fetchall();

Modifié par gandalfblanc (26 Apr 2017 - 13:01)
Oui en effet, je n'y avais pas pensé, et ça marche !
Par contre, toujours la même erreur quand j'utilise la méthode fetchall() Smiley ohwell
Attention pour fetchAll(), il faut l'écrire avec le A majuscule comme dans la documentation PHP.

Autre point venant de la doc de PHP sur l'utilisation de la méthode query de PDO Si vous ne récupérez pas toutes les données du jeu de résultats avant d'exécuter le prochain appel à PDO::query(), votre appel peut échouer. Appeler PDOStatement::closeCursor() pour libérer les ressources de la base de données associées à l'objet PDOStatement avant d'exécuter votre prochain appel à la fonction PDO::query().

Donc dans le code tu peux essayer ça avant de faire ta 2ème requête.
$reponse->closeCursor();

Modifié par gandalfblanc (26 Apr 2017 - 14:28)
Je l'ai modifié et ça ne change rien Smiley ohwell

Concernant la méthode closeCursor(), elle est déjà présente à la fin de mon code, et avant ça supprime des affichages.
Modifié par I--Zop--I (26 Apr 2017 - 14:31)
Ok, sinon sans utiliser fetchAll, tu peux faire une boucle while sur ta requête :

while ($donnees1 = $reponse1->fetch(PDO::FETCH_ASSOC)){ 
                  le texte à afficher ou la donnée à récupérer
}
$donnees1->closeCursor();

La boucle va tournée tant que tu auras une réponse à ta requête.
Modifié par gandalfblanc (26 Apr 2017 - 14:39)
Meilleure solution
Ok c'est parfait merci ! La moitié du chemin est faite ! (J'ai remplacé donnees1 par reponse1)

Voici comment les résultats s'affichent :
2017-07-07 18:00:00
2017-07-07 20:30:00


Auriez-vous une idée de comment je peux faire pour afficher cela comme ceci ?
Vendredi 07 Juillet à 18h00 et 20h30

Modifié par I--Zop--I (26 Apr 2017 - 14:48)
à l'aide des fonctions de date de PHP.


$stringDate1= "2017-07-07 18:00:00";
$stringDate2= "2017-07-07 20:30:00";
/* on converti en timestamp les valeurs */
$timeStringDate1=strtotime($stringDate1);
$timeStringDate2=strtotime($stringDate2);

/* On joue avec la fonction date et ses paramètres */

echo date ('l d F', $timeStringDate1);
echo " à ".date ('H',$timeStringDate1)."h".date ('i',$timeStringDate1);
echo " et ".date ('H',$timeStringDate2)."h".date ('i',$timeStringDate2);


il faut jouer ensuite sur la langue mais ça c'est normalement fait selon ton code. Smiley lol
Modifié par gandalfblanc (26 Apr 2017 - 15:48)
D'accord, alors voila ce que j'ai fais pour le moment :


$timeStringDate=strtotime($donnees1['seances']);
echo "".date ('D',$timeStringDate)." ".date ('d',$timeStringDate)." ".date ('F',$timeStringDate)." ".date ('H',$timeStringDate)."h".date ('i',$timeStringDate).", ";
echo "<br />";


Et voila le résultat (je m'occupe de la langue plus tard Smiley lol )

Fri 07 July 18h00, 
Fri 07 July 20h30, 


Or, ces 2 séances sont le même jours. Comment faire pour que chaque jour soit uniquement sur 1 ligne ?

Par exemple, pour cet événement voici le résultat :

Mon 10 July 14h30, 
Mon 10 July 18h00, 
Mon 10 July 20h30, 
Tue 11 July 14h30, 
Tue 11 July 18h00, 
Tue 11 July 20h30, 
Wed 12 July 14h30, 
Wed 12 July 18h00, 
Wed 12 July 20h30, 


Que ce soit comme ceci :

Mon 10 July 14h30, 18h00, 20h30
Tue 11 July 14h30, 18h00, 20h30
Web 12 July 14h30, 18h00, 20h30
Tu peux nous remettre ton code à partir d'ici :

 
while ($donnees = $reponse->fetch())
                    {

                    setlocale(LC_ALL, 'French', 'fr-FR.utf8','fra', 'fr-FR', 'fr_FR', 'fr', 'fr_FR@euro');
                    $datedebut = strftime("%d %B", 


C'est la boucle qui viens après ta première requête sur ta BDD

merci,
Le voici :

while ($donnees = $reponse->fetch())
                    {

                    setlocale(LC_ALL, 'French', 'fr-FR.utf8','fra', 'fr-FR', 'fr_FR', 'fr', 'fr_FR@euro');
                    $datedebut = strftime("%d %B", strtotime($donnees['premiereSeance']));
                    $datefin = strftime("%d %B %Y", strtotime($donnees['derniereSeance']));

                    $reponse1 = $bdd->query("SELECT dateheure_seance AS seances FROM seance s WHERE s.id_event = '".$donnees['id_event']."'");


                    if( $donnees['derniereSeance'] >= $datecourante )
                    {
                ?>
                    <tr class="infotournee infotournee<?php echo ($compteur%2); $compteur++; ?>">
                        <td id="event<?php echo $donnees['id_event']; ?>"><p style="color:white;" class="villetournee"><?php echo ''.$donnees['ville'].'';?></p> <p class="nomtournee"><?php echo ''.$donnees['nomtournee'].'';?></p></td>
                        <td><?php echo (strpos($datedebut,' '.$datefin))? 'Le '.utf8_encode($datedebut) : 'Du '.utf8_encode($datedebut).'<br/>au '.utf8_encode($datefin); ?></td>
                        <td><?php echo ''.$donnees['adresse'].'';?></td>
                        <td><a href="#spoiler<?php echo $donnees['id_event']; ?>" class="spoiler-link lienresa">PLUS D'INFOS</a><a class="lienresa" href="#">RESERVER</a></td>
                    </tr>
                    <tr>
                        <td colspan="4">
                            <div class="spoilers">
                                <div class="spoiler" id="spoiler<?php echo $donnees['id_event']; ?>">
                                    <p>
                                      <?php 
                                        while ($donnees1 = $reponse1->fetch(PDO::FETCH_ASSOC))
                                        { 
                                          $timeStringDate=strtotime($donnees1['seances']);
                                          echo "".date ('D',$timeStringDate)." ".date ('d',$timeStringDate)." ".date ('F',$timeStringDate)." ".date ('H',$timeStringDate)."h".date ('i',$timeStringDate).", ";
                                          echo "<br />";
                                        }
                                        $reponse1->closeCursor();
                                      ?>
                                    </p>
                                </div>
                            </div>
                        </td>
                    </tr>
                    
                <?php
                    }
                    }
                        $reponse->closeCursor();
                ?>
        </table>
Là l'idée ça va être de stocker les données que tu récupères dans un tableau puis de faire le traitement du tableau et afficher les résultats.

while ($donnees1 = $reponse1->fetch(PDO::FETCH_ASSOC))
                                        {
                   $MonTableauAtraiter[]=$donnees1;
}
                                        $reponse1->closeCursor();


Je regardes le traitement, car celui-ci m’intéresse pour me propre dev.
Pages :