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 de recherche et apostrophe [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Membre éprouvé Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Par défaut Requête de recherche et apostrophe
    Bonjour à tous,

    Avant de poster, j'ai consciencieusement regardé les diverses docs traitant du sujet, et il n'en manque pas...

    Le champ varchar de ma table contient la chaîne :

    Poudre d\'Origan pour pizza
    La clause where de la requête - avec le mot clé "poudre d'origan" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    WHERE nom LIKE '%".mysql_real_escape_string($_GET['motcle'])."%'
    Comme de bien entendu, pas de résultat retourné.
    Avec addslashes ? Pareil !
    Avec sprintf, comme vu dans ce forum ? idem.

    Alors que "poudre" ou "origan" sont trouvés.

    Et le plus bizarre, c'est que le moteur de recherche de phpMyAdmin ne trouve pas mieux même si on utilise %LIKE%...

    Alors il faut y faire quoi, à cette apostrophe ?

  2. #2
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Salut

    Poudre d\'Origan pour pizza
    Pourdre et Origan ont des majuscules, c'est peut être un problème de casse.


    Essai comme ceci pour voir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $motcle = mysql_real_escape_string($_GET['motcle']);
    $sq = "
    SELECT truc
    FROM matable
    WHERE LOWER(nom) LIKE %'".strtolower($motcle)."'%
    ";

  3. #3
    Membre éprouvé Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Par défaut
    Bonjour et merci de me répondre,

    Non, pas mieux.
    Je crois que c'est vraiment l'apostrophe qui coince.
    Parce que "origan" et "Origan" sont trouvés, tout comme "poudre" et "Poudre".

  4. #4
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    J'avais pas fait gaffe à ceci :
    Le champ varchar de ma table contient la chaîne :
    Poudre d\'Origan pour pizza
    Normalement cette donnée dans ta Bdd ne devrait pas être échappée, elle doit être comme ceci : Poudre d'Origan pour pizza
    Ca veut dire que lors de l'insertion ou modification il y a eu des doubles échappement : Poudre d\\'Origan pour pizza

    Dans un 1er temps il faudrait supprimer cet échappement de trop, est fait un essai, ça devrait fonctionner.
    Après ça, il faudrait revoir ces étapes d'insertion ou/et modification de façon qu'il n'y ait plus ces caractères d'échappement.
    Dans ton PhpMyAdmin, tu ne devrait pas les voir.


    Il faudrait que tu vérifie la config du php.ini : magic_quotes_gpc si c'est On ou Off.
    Il est depuis très longtemps maintenant conseillé de mettre Off.
    Si c'est à Off, alors il doit avoir un addslashes par là lors des insertion/modifications.

  5. #5
    Membre éprouvé Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Par défaut
    Humm, oui tu as raison.
    Je viens de tester avec un insert d'apostrophe échappée avec mysql_real_escape_string et c'est inséré "d'origan", sans \ ni ''.

    ...et du coup la requête matche correct.

    J'imagine que cela s'est produit lors d'un export / import de la BDD via phpMyAdmin et un fichier texte.

    Alors...il va falloir que je crée une fonction pour extraire les noms, les nettoyer des antislashes, et les ré-injecter avec mysql_real_escape_string...
    Pas gagné, ça...

    magic_quotes_gpc est à ON.

    Edit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $sql = mysql_query("SELECT id, nom FROM produits");
    while($row = mysql_fetch_assoc($sql)){
    	$nom = stripslashes($row['nom']);
    	mysql_query("UPDATE produits SET nom = '".mysql_real_escape_string($nom)."' WHERE id='".$row['id']."'");
    }
    devrait faire l'affaire.

  6. #6
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    magic_quotes_gpc est à ON.

    Le fond de ton problème vient de là.

    Cette directive échappe automatique tous les ', et du coup, lorsque tu applique un mysql_real_escape_string() lors des insertion/modifs, et bien cette dernière considère que le caractère échappé précédemment fait partie de la chaine (au même titre que les autres caractères), c'est comme ça comme que tu vois ce anti-slash dans PhpMyAdmin.

    Il faudrait redéfinir à Off cette directive, et à l'ensemble de ton application.
    Soit le redéfinir dans le .htaccess, soit en Php avec un ini_set().

    Faut espérer que ton application n'est pas trop volumineuse, mais surtout qu'il y ait pas trop de choses liées à ça, sinon, les effets de bords te guettes.
    Mais c'est quand même la meilleurs chose à faire, car cette directive est vouée à disparaitre, ce qui reviendra au même quelle soir à Off.


    C'est le genre de truc qu'il faut définir dès le départ d'un projet, tout comme le jeu de caractère, etc ...

  7. #7
    Membre éprouvé Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Par défaut
    Le fond de ton problème vient de là
    Tu es sûr de ça ?
    Parce que je viens de tester un insert via un formulaire et un nom apostrophé que j'ai échappé dans l'insert avec mysql_real_escape_string et il est arrivé dans la base :

    L'apostrophe
    Et non pas L\'apostrophe ou L''apostrophe.

  8. #8
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    devrait faire l'affaire.
    A mon avis non.
    Le mal est déjà fait, ces caractères à lors actuel font partie des noms au même titre que toutes les autres caractères.

    Si tu souhaite réparer ça de manière automatique, il n'y a pas d'autre choix que de les supprimer.
    Le problème de faire ça automatiquement, c'est qu'il faut espérer que ce caractère \ soient réellement de trop pour toutes le données, sans exception aucune.
    Faut faire le point la dessus, et sur toute des données.


    Il ne faut pas perdre de vu que le fond du problème vient de cette directive magic_quotes_gpc à On alors quelle doit être à Off.

  9. #9
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Tu es sûr de ça ?
    Certain.
    magic_quotes_gpc à On échappe automatiquement ces caractère, elle a été créé pour ça.
    La communauté Php à reconnu que c'était une vrai fausse bonne idée.


    Le problème, c'est qu'il faudrait passer en revu ton code pour voir vraiment comment tu procède lors de ces insertions/modification.
    Rien ne dit que dans ton code il y a un stripslashes par là général qui résout en partie ce problème.

    Mais comme cette directive est général à Php, PhpMyAdmin est lui peut être affectée par ça.
    C'est peut être de là que ces anti-slash ont été rajoutés, ou par un code indépendant de ton projet, qui lui n'appliquait pas de stripslashes.
    Faut voir.


    Bref ... les choses peuvent s'expliquer, mais ce qui est certain c'est qu'avoir ce magic_quotes_gpc à On ne fait que rendre le choses plus compliquées quelles le sont.
    C'est pour ça que c'était un mauvaise idée.

  10. #10
    Membre Expert
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 149
    Par défaut
    On peut cependant passer par un script automatique pour les supprimer les \
    Pour vérifier qu'on enlève pas des \ qu'il ne faudrait pas on peut utiliser un double stripslashes() avec des méthodes de similitude ou de taille de chaîne.

    Si après effectué le second stripslashes() tu as encore une différence avec le résultat du premier c'est que la chaîne était protégée correctement et qu'il ne faut pas y toucher.
    Cela ne gère cependant pas les cas avec des trucs du genre \\\\\\\ et j'en passe... Mais à priori tu n'as qu'un soucis de \

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 28
    Par défaut
    Juste pour info, j'avais des soucis à cause des apostrophes, je me disais, mince alors, la base ne les veux pas, mais en faite, c'est lors du script, car, une requête peut contenir, comme séparateur, des apostrophe et donc si tu en met en plus dans ta chaine de caractère, ou dans les environs, patatra, y a confusion.

    La solution donnée plus haut règle le problème :
    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $nom = mysql_real_escape_string($nom)
    où dans la variable $nom tu peux mettre des apostrophes entre autres, puis tu insère cette variable dans le query.

    mais y a pas que là où tu peux rencontrer des soucis, personnellement j'ai galéré à certains moment, regarde l'exemple qui suit :

    exemple qui ne marche pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    echo "<input type='hidden' name='query' value='".$query."' />";
    ...
    Ici on voit que l'apostrophe de value qui entoure $query posée problème (puisque $query possède aussi des apostrophes)

    résolution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ...
    ?>
    <input type="hidden" name="query" value="<?php echo $query ; ?>" />
    <?php
    ...
    Donc, plus généralement, c'est qu'en tu tape ton code qu'il faut avoir en tête du possible problème qui peut s'en suivre.

    Edit :ton code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE nom LIKE '%".mysql_real_escape_string($_GET['motcle'])."%'
    Je ne sais pas si le simple quote entourant motcle pose ou pas problème, mais peux tu essayer de mettre une variable ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $motcle=@$_GET['motcle'];
    $motcle=mysql_real_escape_string($motcle);
    $query = ... WHERE nom LIKE '%".$motcle."%';

  12. #12
    Membre éprouvé Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Par défaut
    Merci à vous tous, pour vos diverses interventions.

    Oui, mon problème est que le champ varchar qui m'intéresse pour ma recherche est plein d\'apostrophes.

    J'ai exécuté la petite fonction que j'ai écrite plus haut : d'abord un strioslashes puis un mysql_real_escape_string et tout est rentré dans l'ordre.

    l\'apostrophe est bien devenue l'apostrophe...et du coup, mon moteur de recherche la trouve bien.

    Je considère donc ce post comme résolu.
    Un merci tout spécial à RunCodePhp qui m'a bien mis sur la voie.

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

Discussions similaires

  1. Optimisation d'une requête de recherche
    Par Bobtop dans le forum Requêtes
    Réponses: 16
    Dernier message: 14/06/2006, 16h27
  2. Requête de recherche dans un forum
    Par Gwipi dans le forum Requêtes
    Réponses: 3
    Dernier message: 18/05/2006, 11h38
  3. requête sur recherche d'un mot
    Par Yaone dans le forum Langage SQL
    Réponses: 7
    Dernier message: 12/04/2006, 09h54
  4. [XPATH] [XML] [JAVASCRIPT] Pb de recherche avec apostrophe
    Par lenoil dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 21/02/2006, 14h28
  5. Requête sélection : recherche par nom
    Par leeloo77 dans le forum Access
    Réponses: 7
    Dernier message: 17/02/2006, 15h39

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