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 avec like


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Janvier 2013
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Janvier 2013
    Messages : 11
    Par défaut Requête avec like
    Bonjour,

    j'ai la requête suivante :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM livres WHERE $critere LIKE '%$mot%' ORDER BY $critere $ordre

    et j'aimerais la réécrire en PDO.

    Voici comment je l'ai réécris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $req = $bdd->prepare('SELECT * FROM livres WHERE :critere LIKE :mot ORDER BY :critere :ordre');
    		$req->execute(array(
    			'mot' => $mot_cle,
    			'critere' => '%$critere%',
    			'ordre' => $ordre));
    Mais quand je fais un test, avec un formulaire d'une autre page, ça n'affiche rien. Et pourtant, j'ai choisi un mot qui se trouve dans la base de données.

    Donc, est-ce quelqu'un pourrait m'aider en me disant ce qui ne va pas dans ma requête ?

    Merci d'avance.

    Si besoin est voici mes deux pages :

    d'abord la page du formulaire :

    Code html : 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
    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8" />
    		<link rel="stylesheet" type="text/css" href="aspect.css" />
     
    		<style type="text/css">
                            body { background-color: lightyellow; }
                            div { margin: 100px 0px 50px; height: 320px; }
                            legend { font-size: 1.8em; }
                            .en_gras { font-weight: bold; }
                            hr { margin-top: 20px; width: 90%; }
                    </style>
     
    	</head>
     
    	<body>
     
    		<div>
     
    			<form action="resultat_recherche.php" method="post">
     
    				<fieldset>
    					<legend class="en_gras">Recherche d'un livre</legend>
     
    						<hr />
     
    						<label for="mot_cle" class="en_gras">Mot(s) à chercher :&nbsp;&nbsp;&nbsp;&nbsp;</label>
    						<input type="text" id="mot_cle" name="mot_cle" size="30" maxlength="20" /><br /><br />
     
    						<label for="critere_recherche" class="en_gras">Critère de recherche :&nbsp;&nbsp;&nbsp;&nbsp;</label>
    						<select name="critere_recherche" id="critere_recherche">
    							<option value="titre">&nbsp;&nbsp;Titre&nbsp;&nbsp;</option>
    							<option value="auteur">&nbsp;&nbsp;Auteur&nbsp;&nbsp;</option>
    							<option value="editeur">&nbsp;&nbsp;Éditeur&nbsp;&nbsp;</option>
    							<option value="date_parution">&nbsp;Date de parution&nbsp;&nbsp;&nbsp;</option>
    						</select><br /><br />
     
    						<p>
    							<span class="en_gras">Par ordre&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
     
    							<input type="radio" name="ordre" value="asc" checked="checked" id="croissant" />
    							<label for="croissant">Croissant&nbsp;</label>
     
    							<input type="radio" name="ordre" value="desc" id="decroissant" />
    							<label for="decroissant">Décroissant&nbsp;</label><br /><br /><br />
     
    						</p>	
     
    						<input type="submit" value="Envoyer" />
    						<input type="reset" value="Effacer" />
     
     
    				</fieldset>
     
    			</form>
     
    		</div>
     
    		<p>
    			<a href="index.html">Page d'accueil</a><br /><br />
     
    			<img src="../images/rechercher.gif" alt="recherche" />
    		</p>
     
    	</body>
    </html>

    et ensuite la page pour l'affiche des données :

    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
    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8" />
    		<link rel="stylesheet" type="text/css" href="aspect.css" />
    	</head>
     
    	<body>
     
    		<?php
     
    		$numpage_cible = "resultat_recherche";
     
    		$numpage_source = $_GET['num_page'];
     
    		$mot_cle = utf8_decode(htmlspecialchars($_POST['mot_cle']));
    		$critere = utf8_decode(htmlspecialchars($_POST['critere_recherche']));
    		$ordre = utf8_decode(htmlspecialchars($_POST['ordre']));
     
    		try
    		{
    			$bdd = new PDO('mysql:host=localhost;dbname=bibliotheque', 'root', '');
    		}
    		catch (PDOException $e)
    		{
    			echo 'La base de données est actuellement indisponible, revenez plus tard !';
    		}
     
    		$req = $bdd->prepare('SELECT * FROM livres WHERE :critere LIKE :mot ORDER BY :critere :ordre');
    		$req->execute(array(
    			'mot' => $mot_cle,
    			'critere' => '%$critere%',
    			'ordre' => $ordre));
     
    		while ($donnees = $req->fetch())
    		{
    			echo '<p><strong>' . utf8_encode(htmlspecialchars($donnees['titre'])) . '</strong> : ' . utf8_encode(htmlspecialchars($donnees['auteur'])) . '</p>';
    		}
     
    		$req->closeCursor();
     
    	?>
     
    	</body>
    </html>

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur C++
    Inscrit en
    Avril 2012
    Messages
    771
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 771
    Par défaut
    Bonjour,

    'critere' => '%$critere%',
    la variable $critere ne sera pas interprété car tu utilise les caractère '', donc la chaîne de caractère que tu passera à ta requête sql sera : %$critere%.

    Pour que ce soit la valeur de la variable $critere qui soit utilisé il faut soit utiliser les doubles quotes ("") :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'critere' => "%$critere%",
    soit passer par de la concaténation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'critere' => '%' . $critere . '%',
    à toi de voir ce que tu trouve plus lisible.

  3. #3
    Membre habitué
    Inscrit en
    Janvier 2013
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Janvier 2013
    Messages : 11
    Par défaut
    J'ai essayé avec les doubles quotes et avec la concatenation et ça ne donne rien.

  4. #4
    Membre Expert
    Homme Profil pro
    Développeur C++
    Inscrit en
    Avril 2012
    Messages
    771
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 771
    Par défaut
    Tu ne peut pas mettre en paramètre le nom des tables et des colonnes,

    seul les valeurs peuvent être paramétré.

    ta requête donnerait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $req = $bdd->prepare("SELECT * FROM livres WHERE $critere LIKE :mot ORDER BY $critere $ordre");
    		$req->execute( array('mot' => $mot_cle) );
    Vue que le nom de la colonne ne doit pas venir de l'utilisateur il n'y a aucun danger, parcontre la valeur qui peut être la valeur reçu d'un formulaire doit être sécurisé.

  5. #5
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2012
    Messages
    631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2012
    Messages : 631
    Par défaut
    cette requête est fausse:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM livres WHERE $critere LIKE '%$mot%' ORDER BY $critere $ordre
    la clause where compare une colonne de ta table à une variable. Or dans ton cas tu ne spécifies pas cette colonne.idem pour ORDER BY

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM livres WHERE colonne LIKE :mot ORDER BY colonne :ordre

  6. #6
    Membre chevronné

    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2011
    Messages
    205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2011
    Messages : 205
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $req = $bdd->prepare('SELECT * FROM livres WHERE :critere LIKE :mot ORDER BY :critere :ordre');
    		$req->execute(array(
    			'mot' => $mot_cle,
    			'critere' => '%$critere%',
    			'ordre' => $ordre));
    En remplaçant les variables par leur valeur dans la requête préparée, j'aboutis à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM livres WHERE %$critere% LIKE $mot_cle ORDER BY %$critere% $ordre
    Tu aurais pas inversé $critere et $mot_cle ?

    De plus, tu dois préfixer tes clés par ":" dans ton tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $req->execute(array(
    	':mot' => '%'.$mot_cle.'%',
    	':critere' => $critere,
    	':ordre' => $ordre));
    si ce post vous a été utile, si votre problème est résolu.
    Pensez-y !
    __________________________________
    Doc officielle PHP | FAQ PHP | Cours PHP

  7. #7
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2013
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Services de proximité

    Informations forums :
    Inscription : Février 2013
    Messages : 27
    Par défaut
    Sauf erreur de ma part il est nécessaire de séparer deux clauses de ORDER BY par une virgule, ce qui donnerait le code suivant (en conservant les corrections précédentes)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $req = $bdd->prepare('SELECT * FROM livres WHERE COLONNE1 LIKE :mot ORDER BY COLONNE1, COLONNE2');
    $req->execute(array(':mot' => '%'.$mot_cle.'%');

  8. #8
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    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
    Billets dans le blog
    12
    Par défaut
    Salut,

    Tu dois gérer tes colonnes de filtrage et d'ordonnancement manuellement et pas avec PDO. PDO ne doit s'occuper que des valeurs en provenance de l'utilisateur.

    Les noms des colonnes supportant le filtrage et le tri sont fournies par ton application et pas par l'utilisateur (il ne fait que les sélectionner dans une liste) donc tu dois les contrôler en fonction de ce qu'il est possible de faire. Imagine toi qu'un petit malin modifie manuellement le $_POST et qu'il te renvoie $_POST['critere_recherche'] = 'colonne_inexistante', ton script échouera à chaque fois.

    Ensuite en base de données, on n'utilise pas htmlspecialchars() pour sécuriser les valeurs, cette fonction ne sert qu'à sécuriser le rendu HTML et rien d'autre.

    j'ai repris ton script en tenant compte de ce que j'ai écris plus haut et en essayant de rester explicite :
    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
    <?php
     
    $mot_cle = (isset($_POST['mot_cle']))           ? utf8_decode($_POST['mot_cle'])           : '';
    $critere = (isset($_POST['critere_recherche'])) ? utf8_decode($_POST['critere_recherche']) : '';
    $ordre   = (isset($_POST['ordre']) )            ? utf8_decode($_POST['ordre'])             : '';
     
    if (in_array($critere, array('titre', 'auteur', 'editeur', 'date_parution'), true))
    {
        $colonne = $critere;
    }
    else
    {
        echo 'Erreur : critère de filtrage invalide.';
        exit;
    }
     
    // si l'ordre de tri est incorrect ou inexistant par défaut : asc
    $tri = (in_array($ordre, array('asc', 'desc'), true)) ? $ordre : 'ASC';
     
    try
    {
        $pdo = new PDO('mysql:host=localhost;dbname=bibliotheque', 'root', '');
    }
    catch (PDOException $e)
    {
        echo 'La base de données est actuellement indisponible, revenez plus tard !';
        exit;
    }
     
    $sql =
    <<<SQL
      SELECT *
        FROM livres
       WHERE {$colonne} LIKE CONCAT('%', :mot, '%')
    ORDER BY {$colonne} {$tri}
    SQL;
     
    $req = $pdo->prepare($sql);
    $req->execute(array(':mot' => $mot_cle);
     
    // on factorise l'échappement et l'encodage
    $hsc = function($p) { return htmlspecialchars(utf8_encode($p), ENT_QUOTES, 'UTF-8'); };
    ?>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" type="text/css" href="aspect.css" />
    </head>
    <body>
        <?php while ($v = $req->fetch()): ?>
        <p><strong><?php echo $hsc($v['titre']) ?></strong> : <?php echo $hsc(v['auteur']) ?></p>
        <?php endwhile ?>
    </body>
    </html>
    Une dernière chose, tu n'aurais pas à trimbaler les fonctions utf8_decode()/utf8_encode si tu prenais la peine d'encoder tes fichiers php en utf-8 sans BOM. Si t'es cohérent au niveau des encodages sur toute la ligne : scripts PHP (utf-8 sans BOM), base de données (collation utf-8) et charset HTML (utf-8), tu n'auras plus qu'à utiliser les fonctions mb_str* pour gérer correctement les chaines et rien d'autre (plus aucune prise de tête sur les encodages)

    allez bon codage

  9. #9
    Membre habitué
    Inscrit en
    Janvier 2013
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Janvier 2013
    Messages : 11
    Par défaut problème commentaire
    Merci pour ton aide rawsrc, j'ai écrit tout ton code (ligne par ligne) pour comprendre son fonctionnement. Par contre pour l'execution, j'ai un problème de commentaires, je crois.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $sql =
    <<<SQL
      SELECT *
        FROM livres
       WHERE {$colonne} LIKE CONCAT('%', :mot, '%')
    ORDER BY {$colonne} {$tri}
    SQL;
    Tout ce qui vient après <<<SQL est en commentaires. Alors est-ce que je dois enlever <<<SQL SQL; ? Et si oui, j'ai l'erreur suivante :

    Parse error: syntax error, unexpected T_STRING in C:\wamp\www\mes_livres\resultat_recherche.php on line 33
    Voici la ligne 33 :


    qui fait partie de la requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $sql = 
    	SELECT *
    	FROM livres
    	WHERE {$colonne} LIKE CONCAT('%', :mot, '%')
    	ORDER BY {$colonne} {$tri};

Discussions similaires

  1. Optimiser ma requète avec like
    Par vb dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 06/11/2008, 15h45
  2. requête avec LIKE et IN ensemble
    Par mdr_cedrick dans le forum Langage SQL
    Réponses: 2
    Dernier message: 17/03/2008, 11h02
  3. Pb Requête avec Like
    Par Syrrus dans le forum VBA Access
    Réponses: 7
    Dernier message: 21/11/2007, 17h34
  4. [Débutant] Requête avec Like
    Par nellynew dans le forum Access
    Réponses: 3
    Dernier message: 27/09/2006, 07h30
  5. Requête avec like et un champ de formulaire
    Par Sly2k dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 31/07/2006, 15h46

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