2010-01-20 12 views
3

En accédant à ma base de données, l'utilisateur remplit un formulaire et, dans la page cible, les valeurs affichées sont utilisées dans la requête MySQL résultante.

$query = mysql_query("SELECT pass FROM database WHERE user='$_POST[user]'"); 

Cependant, pour une raison ou une autre, MySQL n'aime pas mon utilisation d'une variable $ _POST dans la commande, et il ne fonctionne que si je define (par exemple) $user = $_POST['user'];, puis mis directement utilisateur $ en la commande SQL.

D'autre part, je peux utiliser $ _POST valeurs dans les instructions INSERT où les noms de colonnes spécifiques ne sont pas nécessaires:

$query = mysql_query("INSERT INTO database VALUES ('foo', 'bar', '$_POST[user]'"); 

Si je tente une instruction INSERT où les attributs sont définis (par exemple user='foo'), le le même problème apparaît. Qu'est-ce que je fais de mal dans ma requête SQL qui provoque l'erreur lors de l'exécution de la commande, mais qui fonctionne avec la méthode spécifique de formatage d'une commande INSERT?

Espérons que ce n'est pas «difficile, vous devez attribuer toutes vos valeurs affichées». Il h.

Répondre

10

Tout d'abord, watch out for SQL Injections!

Maintenant, pour répondre à votre question essayer de faire ceci:

$query = mysql_query("SELECT `pass` FROM `database` WHERE `user` LIKE '" . mysql_escape_string($_POST['user']) . "';"); 

Vous faisiez quelques mauvaises choses:

  • en utilisant l'opérateur = au lieu de LIKE opérateur
  • pas enfermer la valeur dans la requête SQL avec '
  • n'incluant pas l'index utilisateur dans letableauavec '

PS: Vous devez utiliser mysql_real_escape_string() au lieu de mysql_escape_string()!

+1

Vous n'avez qu'à demander, pourquoi utiliser like, quand la chaîne n'est pas destinée à contenir des symboles%? – JAL

+1

@Salsa: Pour plusieurs raisons, voir http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html –

+0

Wow, quelques bons conseils ici, avec toutes les autres réponses. Bon avertissement à propos de l'injection SQL, aussi bien ... doit réorganiser mon code ASAP. –

3

Vous insérez simplement une variable dans une chaîne, peu importe la commande dans laquelle vous l'insérez.

Il y a quelques problèmes à signaler. Un, vous voudrez peut-être utiliser le format {} pour les variables de tableau. Vous n'utilisez pas de guillemets autour des noms de clés arrear dans ce format.

$query = mysql_query("SELECT pass FROM database WHERE user='{$_POST[user]}'") 

Deux, tu ne veux jamais faire une requête comme celle parce que vous êtes ouvert à des trous d'injection sql. Considérez, et si $ _POST ['user'] était "vache", drop table de base de données; - "? Vous devez exécuter mysql_real_escape_string sur l'entrée POST avant de l'insérer dans votre requête, ou extraire avec PHP PDO avec les instructions préparées.

Une façon de formater votre chaîne qui fournit un peu de structure est d'utiliser sprintf.

$query=mysql_query(sprintf("SELECT pass FROM database WHERE user='%s'",mysql_real_escape_string($_POST['user']))); 
+0

+1 pour avoir démarré avec la raison pour laquelle la référence de variable d'OP n'a pas été analysée correctement http://www.php.net/manual/fr/language.types.string.php#language.types.string.parsing –

0

Essayez

$query = mysql_query("SELECT pass FROM database WHERE user=" . mysql_real_escape_string($_POST['user'])); 

et

$query = mysql_query("INSERT INTO database VALUES ('foo', 'bar', " . mysql_real_escape_string($_POST['user']) . ")"); 

toujours une bonne idée de désinfectez quoi que ce soit reçu par _GET $ ou _POST

1

$ Pourquoi ne pas vérifier et voir ce que mysql_error () a à dire à ce sujet? Si votre requête est invalide, mysql_error() renverra une petite goutte de texte vous indiquant exactement ce qui n'a pas fonctionné. Comme MySQL n'aime pas le POST var si vous l'insérez directement pour certaines exécutions, mais pas d'autres, vous devez vous assurer que vous utilisez des données et des configurations cohérentes pour chaque test. Si certains tests sont effectués à l'aide d'un GET, vos variables POST seront vides. Si vous utilisez des noms d'utilisateur différents pour chaque test, vérifiez si ce qui est cohérent entre ceux qui échouent. Et comme mentionné ci-dessus, lisez l'article sur l'injection SQL et comment votre requête ne demande qu'à être corrompue par un utilisateur malintentionné.

2
  1. Utilisez PDO - il fournit beaucoup mieux API pour communiquer avec DB.
  2. Si vous utilisez les fonctions mysql_*() pensez toujours à filtre (mysql_real_escape_string()) toutes les données qui provient de source non fiable (comme utilisateur)
  3. accorder plus d'attention à la façon dont votre code ressemble. Il suffit de comparer les listes suivantes:

    $query = mysql_query("INSERT INTO database VALUES ('foo', 'bar', " . mysql_real_escape_string($_POST['user']) . ", " . mysql_real_escape_string($_POST['user']) . ", " . mysql_real_escape_string($_POST['user']) . ", " . mysql_real_escape_string($_POST['user']) . ")"); 
    
    $query = sprinf('INSERT INTO database VALUES ("foo", "bar", "%s", "%s", "%s")', 
    mysql_real_escape(...), ...); 
    

    Dois-je expliquer lequel est préférable de lire, de modifier ou de comprendre?

+1

I deuxième AOP, apprenez-le, utilisez-le, aimez-le.Sauf si vous travaillez dans un bon cadre, alors utilisez leur. – Clutch

+0

D'accord, PDO est de loin supérieur aux fonctions de base mysql_ *. – JAL

+0

(Plusieurs mois plus tard) - définitivement en utilisant PDO maintenant. –