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 :

Requête préparée qui ne fonctionne pas [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Conseil en assistance à maîtrise d'ouvrage
    Inscrit en
    Juin 2019
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Conseil en assistance à maîtrise d'ouvrage

    Informations forums :
    Inscription : Juin 2019
    Messages : 28
    Points : 8
    Points
    8
    Par défaut Requête préparée qui ne fonctionne pas
    Bonjour,
    J'ai préparé un formulaire de recherche interrogeant une base qui recense des interviews : une table interviews, une table interviewés et une table d'association.
    Pour le moment j'ai seulement une requête de type LIKE qui interroge un champ de texte de la table interviews, mais je dois ajouter des critères de recherche.
    Ceux-ci prendront la forme de cases à cocher dans le formulaire, ce qui engendre une succession de conditions WHERE que je veux concaténer si le critère est présent dans $_POST.
    (j'espère que cette présentation est claire...)
    J'ai donc voulu préparer ma requête en écrivant "WHERE ?" et en l'exécutant avec dans l'array une variable $criteres qui contient la concaténation desdits critères issus de $_POST.
    Pour le moment, je n'ai mis en place que le critère LIKE... mais ça ne fonctionne déjà pas !
    Je pense que ma syntaxe est mauvaise, sans doute dans la variable $critere peut-être ?

    voici mon 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
    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
     
    <?php
    if(isset($_POST) && $_POST['motscles'] != NULL)
    	{
     
    		// connexion bdd
    		try
    		{
    			$bdd = new PDO('mysql:host=localhost;dbname=base;charset=utf8', 'root', '');
    			$bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    		}
    		catch(Exception $e)
    		{
    		        die('Erreur : '.$e->getMessage());
     
     
    		}
     
    		// on prépare la requête mySQL
    		$reponse = $bdd->prepare("SELECT GROUP_CONCAT( CONCAT(t.civilite, ' ', t.prenom, ' ', t.nom, ', ', t.qualite) ORDER BY t.nom SEPARATOR ' ~~ ') AS groupe, i.id, i.nom_fichier
    					FROM temoins as t
    					INNER JOIN asso_temoins ON t.id = temoin_id
    					INNER JOIN temoignages as i ON i.id = temoignage_id
    					WHERE ?
    					GROUP BY i.id
    					ORDER BY i.nom_fichier");
     
     
    		// on construit le WHERE de la requête en concaténant les critères de recherche présent dans $_POST
     
    		if(isset($_POST['motscles']) && $_POST['motscles'] != NULL)
    			$chaine = htmlspecialchars($_POST['motscles']);
    			$criteres = "i.retranscription LIKE '%$chaine%'";
     
     
     
    		// on exécute le requête et on affiche les résultats
     
    		$reponse->execute(array($criteres));
     
    		if ($reponse->rowCount() == 0) {
    		   echo 'Aucun résultat<br /><a href="recherche.php">Retour au formulaire de recherche</a>';
    		}
    		else{
     
    				?>
     
    				<p>
    					<?php
    					if ($reponse->rowCount() == 1)
    					{echo '1 résultat :';}
    					else {echo $reponse->rowCount(). ' résultats :';}
    					?>
    				</p>
     
    				<?php
     
    				while ($donnees = $reponse->fetch())
    				{
    					?>
    					    <p>
    					    	<a href="temoignage.php?id=<?php echo $donnees['id']?>">
    					    		Témoignage de&nbsp;
    					    		<?php echo $donnees['groupe'];?>
    					    	</a>
    					    </p>
    					<?php
    				}
    			}
     
    			$reponse->closeCursor(); // Termine le traitement de la requête
     
    		}
     
    else
    	{echo '
    	Veuillez taper un mot-clé ou sélectionner au moins un critère de recherche avancée<br />
    	<a href="recherche.php">Retour au formulaire de recherche</a>
    	' ;}
     
    ?>
    Le résultat obtenu est mon " echo 'Aucun résultat ", autrement dit il n'arrive pas à prendre en compte la chaîne de caractères à rechercher

    Je précise que la requête fonctionne lorsqu'elle n'est pas préparée, c'est-à-dire avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    $reponse = $bdd->query("SELECT GROUP_CONCAT( CONCAT(t.civilite, ' ', t.prenom, ' ', t.nom, ', ', t.qualite) ORDER BY t.nom SEPARATOR ' ~~ ') AS groupe, i.id, i.nom_fichier
    								FROM temoins as t
    								INNER JOIN asso_temoins ON t.id = temoin_id
    								INNER JOIN temoignages as i ON i.id = temoignage_id
    								WHERE i.retranscription LIKE '%$chaine%'
    								GROUP BY i.id
    								ORDER BY i.nom_fichier");
    Merci beaucoup d'avance pour votre aide !

  2. #2
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,

    effectivement tu ne peux pas procéder ainsi car pour que la préparation de la requête fonction il faut obligatoirement qu'elle soit détaillée au moment de la préparation donc il faut qu'elle ait des placeholder dans sa définition.
    Pour cela il faut compiler les valeurs des cases à cocher et leur allouer des :tags
    Poste voir le code source du formulaire, stp.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Conseil en assistance à maîtrise d'ouvrage
    Inscrit en
    Juin 2019
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Conseil en assistance à maîtrise d'ouvrage

    Informations forums :
    Inscription : Juin 2019
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Merci, je m'en doutais un peu mais je suis perdu !
    Voici le code du formulaire: en plus du champ de texte (pour la requête LIKE), les 3 cases à cocher interrogeront trois champs de la table temoignages "audio", "video", "documents" qui bien sûr peuvent avoir pour valeur 0 ou 1

    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
    <form method="post" action="resultats.php">
     
    				<p>
    					<label for="motscles">Saisissez votre recherche</label> : <input type="text" name="motscles" id="motscles" />
    				</p>
     
    				<br />
     
    				<details>
    					<summary>Recherche avancée</summary>
    					<fieldset>
    						<p><em>
    							Tous les témoignages ont une version texte. La plupart ont une version audio et, en fonction de l'accord des témoins, presque tous une vidéo.<br />
    							Vous pouvez ici filtrer la recherche pour afficher seulement les résultats comportant obligatoirement au moins de l'audio / de la vidéo.<br />
    							Vous pouvez également n'afficher que les témoignages où des documents (photos, archives, etc.) sont présentés par les témoins.
    						</em></p>
    						<ul class="liste-cases">
    							<li><input type="checkbox" name="audio" id="audio" /> <label for="audio">Témoignages comportant obligatoirement un fichier audio</label></li>
    							<li><input type="checkbox" name="video" id="video" /> <label for="video">Témoignages comportant obligatoirement un fichier vidéo</label></li>
    							<li><input type="checkbox" name="documents" id="documents" /> <label for="documents">Témoignages dans lesquels des documents sont présentés</label></li>
    						</ul>
    					</fieldset>
    				</details>
     
    				<br />
     
    				<input type="submit" value="Valider" />
     
    			</form>

  4. #4
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    c'est un poil plus compliqué que tu ne te l'imagine :
    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    <?php
     
    // interception d'absence de mots clés
    if (empty($_POST['motscles'])) {
        echo <<<'html'
    Veuillez taper un mot-clé ou sélectionner au moins un critère de recherche avancée<br />
    <a href="recherche.php">Retour au formulaire de recherche</a>
    html;
        exit;
    }
     
    // traitement de la recherche
    // connexion bdd
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=base;charset=utf8', 'root', '', [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false
        ]);
    } catch(Exception $e) {
        die('Erreur : '.$e->getMessage());
    }
     
    $where = [];
    $data  = [];
    $type  = [];    // types de données pour PDO
     
    // construction de la clause WHERE
    $data[':motscles'] = '%'.$_POST['motscles'].'%';
    $type[':motscles'] = PDO::PARAM_STR;
    $where[]           = 'i.restranscription LIKE :motscles';
     
    if (isset($_POST['audio'])) {
        $cac = (int)$_POST['audio'];
        $data[':audio'] = ($cac === 0) ? 0 : 1;  // on s'assure que l'on aura que des 1 ou des 0
        $type[':audio'] = PDO::PARAM_INT;
        $where[]        = 'i.audio = :audio';
    }
     
    if (isset($_POST['video'])) {
        $cac = (int)$_POST['video'];
        $data[':video'] = ($cac === 0) ? 0 : 1;  // on s'assure que l'on aura que des 1 ou des 0
        $type[':video'] = PDO::PARAM_INT;
        $where[]        = 'i.video = :video';
    }
     
    if (isset($_POST['document'])) {
        $cac = (int)$_POST['document'];
        $data[':document'] = ($cac === 0) ? 0 : 1;  // on s'assure que l'on aura que des 1 ou des 0
        $type[':document'] = PDO::PARAM_INT;
        $where[]           = 'i.document = :document';
    }
     
    $where = empty($where) ? '' : ' WHERE '. implode(' AND ', $where);
     
    $sql = <<<sql
    SELECT GROUP_CONCAT( CONCAT(t.civilite, ' ', t.prenom, ' ', t.nom, ', ', t.qualite) ORDER BY t.nom SEPARATOR ' ~~ ') AS groupe, i.id, i.nom_fichier
    FROM temoins as t
       INNER JOIN asso_temoins at  ON at.temoin_id = t.id
       INNER JOIN temoignages  i   ON i.id         = at.temoignage_id
    {$where}
    GROUP BY
       i.id
    ORDER BY
        i.nom_fichier
    sql;
     
    $stmt = $pdo->prepare($sql);
     
    // injection des valeurs dynamiques
    foreach ($data as $tag => $v) {
        $stmt->bindValue($tag, $v, $type[$tag]);
    }   
    $exec = $stmt->execute();
    $data = $stmt->fetchAll;
     
    if (empty($data)) {
       echo 'Aucun résultat<br /><a href="recherche.php">Retour au formulaire de recherche</a>';
    } else {
        $nb = count($data);
        echo '<p>', $nb, ' résultat', ($nb > 1) ? 's' : '', '</p';
     
        // échappement des caractères dangereux
        $hsc = function($p) { return htmlspecialchars($p, ENT_QUOTES, 'utf-8'); };
     
        foreach ($data as $v) {
            echo <<<html
    <p><a href="temoignage.php?id={$v['id']}">Témoignage de&nbsp;{$hsc($v['groupe'])}</a></p>
    html;
        }
    }
    comme toujours je n'ai rien testé, ça sort du four.
    par contre ça serait bien que tu indiques la version du PHP en production.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    1-
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (isset($_POST['document'])) {
        $cac = (int)$_POST['video'];
    video au lieu de document ligne 48.


    2- On est d'accord qu'ici, si une checkbox N'est PAS cochée, la requête sera "PAS de....".

    Perso, j'aurais mis des boutons radio : Tous / Oui / Non
    • Tous : (rien dans la requête)
    • Oui : "... = 1"
    • Non : "... = 0"

    C'est plus clair.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Conseil en assistance à maîtrise d'ouvrage
    Inscrit en
    Juin 2019
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Conseil en assistance à maîtrise d'ouvrage

    Informations forums :
    Inscription : Juin 2019
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Merci !
    En effet c'est plus compliqué, mais j'ai compris le raisonnement, c'est déjà ça (sauf la partie "injection des valeurs dynamiques"...).
    ça marche très bien pour la recherche du mot-clé tapé, par contre il ne prend pas en compte les cases à cocher (on dirait qu'il arrête la clause WHERE avant le premier AND ?)
    D'ailleurs, puisque si les cases à cocher sont isset, la valeur recherchée est forcément 1 dans la table, je me demandais si on n'aurait pas pu écrire plus simplement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (isset($_POST['audio'])) {
        $where[]        = 'i.audio = 1';
    }
    au lieu de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if (isset($_POST['audio'])) {
        $cac = (int)$_POST['audio'];
        $data[':audio'] = ($cac === 0) ? 0 : 1;  // on s'assure que l'on aura que des 1 ou des 0
        $type[':audio'] = PDO::PARAM_INT;
        $where[]        = 'i.audio = :audio';
    }
    ?

    Autre problème : ce code semble rendre obligatoire la saisie d'un mot-clé. Dans "interception d'absence de mot-clé" : en fait ce message doit s'afficher si aucun champ du formulaire n'est utilisé (sachant que dans tous les cas on reçoit au moins un champ motscles vide).
    C'est vrai que je ne l'avais pas précisé, désolé, mais en fait ce champ de mot-clé n'est pas obligatoire (on pourrait juste filtrer "documents" sur toutes les interviews par exemple).

    *PHP 7.2.10 / mySQL 5.7.23

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Conseil en assistance à maîtrise d'ouvrage
    Inscrit en
    Juin 2019
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Conseil en assistance à maîtrise d'ouvrage

    Informations forums :
    Inscription : Juin 2019
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par jreaux62 Voir le message
    ...Perso, j'aurais mis des boutons radio : Tous / Oui / Non
    Bonjour et merci, je viens de corriger en effet.
    Cela dit ça ne change rien par rapport à la réponse que je viens de poster... (les cases à cocher ne semblent pas prises en compte)

    C'est-à-dire, trois groupes de boutons radio, un pour chaque critère vidéo / audio / documents ?
    ça permettrait d'afficher éventuellement les interviews qui n'ont pas de vidéo, etc. je n'y avais pas pensé mais c'est intéressant !

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Conseil en assistance à maîtrise d'ouvrage
    Inscrit en
    Juin 2019
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Conseil en assistance à maîtrise d'ouvrage

    Informations forums :
    Inscription : Juin 2019
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Du coup, le code du formulaire devient celui-ci :
    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
    <form method="post" action="resultats.php">
     
    				<p>
    					<label for="motscles">Saisissez votre recherche</label> : <input type="text" name="motscles" id="motscles" />
    				</p>
     
    				<br />
     
    				<details>
    					<summary>Recherche avancée</summary>
    					<fieldset>
    						<p><em>
    							Tous les témoignages ont une version texte. Presque tous ont une version audio et, en fonction de l'accord des témoins, la plupart ont une vidéo.<br />
    							De nombreux témoins présentent des documents (photos, archives, etc.) dans leur témoignage.<br />
    							Vous pouvez ici filtrer la recherche en fonction de ces critères.
    						</em></p>
    						<ul>
    							<input type="radio" name="video" value="tous" id="tous" checked="checked" /> <label for="tous">Afficher tous les résultats</label>
    							<input type="radio" name="video" value="oui" id="oui" /> <label for="oui">Vidéo obligatoire</label>
    							<input type="radio" name="video" value="non" id="non" /> <label for="non">Résultats sans vidéo</label>
    						</ul>
    						<ul>
    							<input type="radio" name="audio" value="tous" id="tous" checked="checked" /> <label for="tous">Afficher tous les résultats</label>
    							<input type="radio" name="audio" value="oui" id="oui" /> <label for="oui">Audio obligatoire</label>
    							<input type="radio" name="audio" value="non" id="non" /> <label for="non">Résultats sans audio</label>
    						</ul>
    						<ul>
    							<input type="radio" name="documents" value="tous" id="tous" checked="checked" /> <label for="tous">Afficher tous les résultats</label>
    							<input type="radio" name="documents" value="oui" id="oui" /> <label for="oui">Documents présentés obligatoire</label>
    							<input type="radio" name="documents" value="non" id="non" /> <label for="non">Résultats sans documents présentés</label>
    						</ul>
    					</fieldset>
    				</details>
     
    				<br />
     
    				<input type="submit" value="Valider" />
     
    			</form>
    Donc oui, avec "tous" => rien dans la requête
    avec "oui" => on recherche les 1 dans le champ
    avec "non" => on recherche les 0 dans le champ

    Reste maintenant à réintégrer ça dans la requête...

  9. #9
    Invité
    Invité(e)
    Par défaut
    Un exemple ici (ouvrir le module de recherche).

    (extrait -> simplifié) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <p>
    	<label>avec Vidéo : </label>
    	<label><input name="avecVideo" type="radio" value="-99" checked="checked"> >Tous </label>
    	<label><input name="avecVideo" type="radio" value="0"> Non </label>
    	<label><input name="avecVideo" type="radio" value="1"> Oui </label>
    </p>
    Mets plutôt en value : -99 / 0 / 1

  10. #10
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    je préfère une liste avec dedans 3 valeurs : Tout | Oui | Non
    donc, 3 select : audio, vidéo et document

  11. #11
    Invité
    Invité(e)
    Par défaut
    Liste déroulante (<select>) ou bouton radio, c'est un choix perso...

    Dans les 2 cas, la récupération est la même.

  12. #12
    Invité
    Invité(e)
    Par défaut
    rawsrc parle de 3 <select>, de cette forme :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <p>
    	<label>avec Vidéo : </label>
    	<select name="avecVideo">
    		<option value="-99" selected="selected"> >Tous </option>
    		<option value="0"> Non </option>
    		<option value="1"> Oui </option>
    	</select>
    </p>
    N.B. Moi, j'ai mis "-99", mais tu peux mettre "".
    Là aussi, c'est un choix perso.

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Conseil en assistance à maîtrise d'ouvrage
    Inscrit en
    Juin 2019
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Conseil en assistance à maîtrise d'ouvrage

    Informations forums :
    Inscription : Juin 2019
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Ok, voici donc le nouveau code du formulaire (connaissant mes utilisateurs, des boutons radio sont préférables).

    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
    <form method="post" action="resultats.php">
     
    				<p>
    					<label for="motscles">Saisissez votre recherche</label> : <input type="text" name="motscles" id="motscles" />
    				</p>
     
    				<br />
     
    				<details>
    					<summary>Recherche avancée</summary>
    					<fieldset>
    						<p>
    							<em>
    							Tous les témoignages ont une version texte. Presque tous ont une version audio et, en fonction de l'accord des témoins, la plupart ont une vidéo.<br />
    							De nombreux témoins présentent des documents (photos, archives, etc.) dans leur témoignage.<br />
    							Vous pouvez ici filtrer la recherche en fonction de ces critères.
    							</em>
    						</p>
    						<p><strong>Vidéo</strong></p>
    						<ul class="liste-recherche">
    							<li><input type="radio" name="avecVideo" value="-99" checked="checked" /> <label for="tous">Afficher tous les résultats</label></li>
    							<li><input type="radio" name="avecVideo" value="1" /> <label for="oui">Vidéo obligatoire</label></li>
    							<li><input type="radio" name="avecVideo" value="0" /> <label for="non">Résultats sans vidéo</label></li>
    						</ul>
    						<p><strong>Audio</strong></p>
    						<ul class="liste-recherche">
    							<li><input type="radio" name="avecAudio" value="-99" checked="checked" /> <label for="tous">Afficher tous les résultats</label></li>
    							<li><input type="radio" name="avecAudio" value="1" /> <label for="oui">Audio obligatoire</label></li>
    							<li><input type="radio" name="avecAudio" value="0" /> <label for="non">Résultats sans audio</label></li>
    						</ul>
    						<p><strong>Documents</strong></p>
    						<ul class="liste-recherche">
    							<li><input type="radio" name="avecDocuments" value="-99" checked="checked" /> <label for="tous">Afficher tous les résultats</label></li>
    							<li><input type="radio" name="avecDocuments" value="1" /> <label for="oui">Documents présentés obligatoires</label></li>
    							<li><input type="radio" name="avecDocuments" value="0" /> <label for="non">Résultats sans documents présentés</label></li>
    						</ul>
    					</fieldset>
    				</details>
     
    				<br />
     
    				<input type="submit" value="Valider" />
     
    			</form>

  14. #14
    Futur Membre du Club
    Homme Profil pro
    Conseil en assistance à maîtrise d'ouvrage
    Inscrit en
    Juin 2019
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Conseil en assistance à maîtrise d'ouvrage

    Informations forums :
    Inscription : Juin 2019
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par jreaux62 Voir le message
    rawsrc parle de 3 <select>, de cette forme :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <p>
    	<label>avec Vidéo : </label>
    	<select name="avecVideo">
    		<option value="-99" selected="selected"> >Tous </option>
    		<option value="0"> Non </option>
    		<option value="1"> Oui </option>
    	</select>
    </p>
    N.B. Moi, j'ai mis "-99", mais tu peux mettre "".
    Là aussi, c'est un choix perso.
    Oui oui... j'avais pas compris sur le coup !

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Conseil en assistance à maîtrise d'ouvrage
    Inscrit en
    Juin 2019
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Conseil en assistance à maîtrise d'ouvrage

    Informations forums :
    Inscription : Juin 2019
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Bien, du côté de la requête, du coup je n'ai plus besoin de ces lignes là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    // interception d'absence de mots clés
    if (empty($_POST['motscles'])) {
        echo <<<'html'
    Veuillez taper un mot-clé ou sélectionner au moins un critère de recherche avancée<br />
    <a href="recherche.php">Retour au formulaire de recherche</a>
    html;
        exit;
    }
    Puisque les mots-cles ne sont plus obligatoires, et qu'on a au moins trois filtres activés avec les boutons radio, donc le $_POST contiendra toujours quelque chose.

  16. #16
    Futur Membre du Club
    Homme Profil pro
    Conseil en assistance à maîtrise d'ouvrage
    Inscrit en
    Juin 2019
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Conseil en assistance à maîtrise d'ouvrage

    Informations forums :
    Inscription : Juin 2019
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    J'ai maintenant le début ma clause where avec les mots-cles non obligatoire de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if ($_POST['motscles'] != NULL) { 
    $data[':motscles'] = '%'.$_POST['motscles'].'%';
    $type[':motscles'] = PDO::PARAM_STR;
    $where[]           = 'i.retranscription LIKE :motscles';
    }

  17. #17
    Futur Membre du Club
    Homme Profil pro
    Conseil en assistance à maîtrise d'ouvrage
    Inscrit en
    Juin 2019
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Conseil en assistance à maîtrise d'ouvrage

    Informations forums :
    Inscription : Juin 2019
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    En faisant ça, il me semble que tout fonctionne (mais je ne suis pas sûr que mon traitement des boutons radios soit vraiment "correct") ?
    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
    83
    84
    85
    86
    87
    <?php
     
    // traitement de la recherche
    // connexion bdd
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=base;charset=utf8', 'root', '', [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false
        ]);
    } catch(Exception $e) {
        die('Erreur : '.$e->getMessage());
    }
     
    $where = [];
    $data  = [];
    $type  = [];    // types de données pour PDO
     
    // construction de la clause WHERE
     
    if ($_POST['motscles'] != NULL) { 
    $data[':motscles'] = '%'.$_POST['motscles'].'%';
    $type[':motscles'] = PDO::PARAM_STR;
    $where[]           = 'i.retranscription LIKE :motscles';
    }
     
    if ($_POST['avecVideo'] != '-99') {
        $cac = (int)$_POST['avecVideo'];
        $data[':video'] = ($cac === 0) ? 0 : 1;  // on s'assure que l'on aura que des 1 ou des 0
        $type[':video'] = PDO::PARAM_INT;
        $where[]        = 'i.video = :video';
    }
     
    if ($_POST['avecAudio'] != '-99') {
        $cac = (int)$_POST['avecAudio'];
        $data[':audio'] = ($cac === 0) ? 0 : 1;  // on s'assure que l'on aura que des 1 ou des 0
        $type[':audio'] = PDO::PARAM_INT;
        $where[]        = 'i.audio = :audio';
    }
     
    if ($_POST['avecDocuments'] != '-99') {
        $cac = (int)$_POST['avecDocuments'];
        $data[':documents'] = ($cac === 0) ? 0 : 1;  // on s'assure que l'on aura que des 1 ou des 0
        $type[':documents'] = PDO::PARAM_INT;
        $where[]        = 'i.docments = :documents';
    }
     
    $where = empty($where) ? '' : ' WHERE '. implode(' AND ', $where);
     
    $sql = <<<sql
    SELECT GROUP_CONCAT( CONCAT(t.civilite, ' ', t.prenom, ' ', t.nom, ', ', t.qualite) ORDER BY t.nom SEPARATOR ' ~~ ') AS groupe, i.id, i.nom_fichier
    FROM temoins as t
       INNER JOIN asso_temoins at  ON at.temoin_id = t.id
       INNER JOIN temoignages  i   ON i.id         = at.temoignage_id
    {$where}
    GROUP BY
       i.id
    ORDER BY
        i.nom_fichier
    sql;
     
    $stmt = $pdo->prepare($sql);
     
    // injection des valeurs dynamiques
    foreach ($data as $tag => $v) {
        $stmt->bindValue($tag, $v, $type[$tag]);
    }   
    $exec = $stmt->execute();
    $data = $stmt->fetchAll();
     
    if (empty($data)) {
       echo 'Aucun résultat<br /><a href="recherche.php">Retour au formulaire de recherche</a>';
    } else {
        $nb = count($data);
        echo '<p>', $nb, ' résultat', ($nb > 1) ? 's' : '', '&nbsp;:</p>';
     
        // échappement des caractères dangereux
        $hsc = function($p) { return htmlspecialchars($p, ENT_QUOTES, 'utf-8'); };
     
        foreach ($data as $v) {
            echo <<<html
    <p><a href="temoignage.php?id={$v['id']}">Témoignage de&nbsp;{$hsc($v['groupe'])}</a></p>
    html;
        }
    }
     
    ?>

  18. #18
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    c'est pas mal, mais tu dois privilégier le mot clé isset() qui lui contrôle 2 choses : l'existence de la variable et que sa valeur est différente de null.
    Regarde la doc php ici

    ensuite pour le cas des choix du style oui/non, tu peux effectivement te passer du mécanisme de préparation et inclure directement tes valeurs dans le sql, à condition que ces valeurs c'est toi qui les fournisse et pas le tableau $_POST.

    Voici une version modifiée :
    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
    <?php
     
    // traitement de la recherche
    // connexion bdd
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=base;charset=utf8', 'root', '', [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false
        ]);
    } catch(Exception $e) {
        die('Erreur : '.$e->getMessage());
    }
     
    $where = [];
    $data  = [];
     
    // construction de la clause WHERE
     
    if (isset($_POST['motscles'])) { 
        $data[':motscles'] = '%'.$_POST['motscles'].'%';
        $where[]           = 'i.retranscription LIKE :motscles';
    }
     
    $choix = [0, 1];
     
    if (isset($_POST['avecVideo'], $choix[$_POST['avecVideo']])) {
        $where[] = "i.video = {$choix[$_POST['avecVideo']]}";
    }
     
    if (isset($_POST['avecAudio'], $choix[$_POST['avecAudio']])) {
        $where[] = "i.audio = {$choix[$_POST['avecAudio']]}";
    }
     
    if (isset($_POST['avecDocuments'], $choix[$_POST['avecDocuments']])) {
        $where[] = "i.documents = {$choix[$_POST['avecDocuments']]}";
    }
     
    $where = empty($where) ? '' : ' WHERE '. implode(' AND ', $where);
     
    $sql = <<<sql
    SELECT GROUP_CONCAT( CONCAT(t.civilite, ' ', t.prenom, ' ', t.nom, ', ', t.qualite) ORDER BY t.nom SEPARATOR ' ~~ ') AS groupe, i.id, i.nom_fichier
    FROM temoins as t
       INNER JOIN asso_temoins at  ON at.temoin_id = t.id
       INNER JOIN temoignages  i   ON i.id         = at.temoignage_id
    {$where}
    GROUP BY
       i.id
    ORDER BY
        i.nom_fichier
    sql;
     
    $stmt = $pdo->prepare($sql);
    $exec = $stmt->execute($data);
    $data = $stmt->fetchAll();
     
    if (empty($data)) {
       echo 'Aucun résultat<br /><a href="recherche.php">Retour au formulaire de recherche</a>';
    } else {
        $nb = count($data);
        echo '<p>', $nb, ' résultat', ($nb > 1) ? 's' : '', '&nbsp;:</p>';
     
        // échappement des caractères dangereux
        $hsc = function($p) { return htmlspecialchars($p, ENT_QUOTES, 'utf-8'); };
     
        foreach ($data as $v) {
            echo <<<html
    <p><a href="temoignage.php?id={$v['id']}">Témoignage de&nbsp;{$hsc($v['groupe'])}</a></p>
    html;
        }
    }
    Un dernier point important, quand ton fichier ne contient que du PHP, prend l'habitude de ne jamais poser le tag de fermeture ?>

  19. #19
    Futur Membre du Club
    Homme Profil pro
    Conseil en assistance à maîtrise d'ouvrage
    Inscrit en
    Juin 2019
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Conseil en assistance à maîtrise d'ouvrage

    Informations forums :
    Inscription : Juin 2019
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Super ! ça marche parfaitement, merci !
    Pour que je comprenne bien, le cas du "-99" est transformé en [0, 1] comme indiqué lors de la déclaration de $choix, sinon, $choix prend la valeur 1 ou 0 qui elle est valide, c'est bien cela ? C'est ce cas que je ne savais pas gérer

    (Et en fait, ce code est à l'intérieur d'un fichier contenant du html et des includes pour mon squelette)

  20. #20
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par burnic Voir le message
    Pour que je comprenne bien, le cas du "-99" est transformé en [0, 1] comme indiqué lors de la déclaration de $choix, sinon, $choix prend la valeur 1 ou 0 qui elle est valide, c'est bien cela ?
    Non la valeur -99 est tout simplement ignorée, tu peux remplacer cette valeur par "magrandmèreadorelevélo" que ça continuera de fonctionner.
    Dans cette version, on ne tient compte que des valeurs importantes : 0 et 1 car elles ont une influence directe sur le SQL.

    Voici ce que je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $choix = [0, 1];  // équivalent à [0 => 0, 1 => 1]
    // le formulaire envoie soit 0 soit 1 en fonction du choix
    // quand je fais
    if (isset($choix[$_POST['avecAudio']]) 
    // je vérifie que la valeur envoyée via $_POST['avecAudio'] correspond à une clé du tableau $choix soit forcément 0 ou 1

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Interbase requête SQL qui ne fonctionne pas
    Par colorid dans le forum InterBase
    Réponses: 6
    Dernier message: 20/11/2007, 17h36
  2. Requête hibernate qui ne fonctionne pas
    Par sheura dans le forum Hibernate
    Réponses: 4
    Dernier message: 28/09/2007, 16h20
  3. requête match qui ne fonctionne pas.
    Par sam01 dans le forum Requêtes
    Réponses: 3
    Dernier message: 29/05/2006, 20h28
  4. [MySQL] Requête update qui ne fonctionne pas
    Par Sylvain245 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 05/12/2005, 16h40
  5. [SQL] Requête à jointure qui ne fonctionne pas
    Par Bensor dans le forum Langage SQL
    Réponses: 2
    Dernier message: 09/12/2004, 16h10

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