2010-09-16 6 views
8

VEUILLEZ LIRE ATTENTIVEMENT LA QUESTION. Ce n'est pas habituel, bête "mon code ne marche pas !!!" question.Fonctionnement de la requête paramétrée par PDO

Quand je lance ce code avec d'erreur destiné

try { 
    $sth = $dbh->prepare("SELECT id FROM users WHERE name INN(?,?) "); 
    $sth->execute(array("I'm","d'Artagnan")); 
} catch (PDOException $e) { 
    echo $e->getMessage(); 
} 

Je reçois ce message d'erreur

Vous avez une erreur dans votre syntaxe SQL ... près de 'INN (' I \ 'm', 'd \' Artagnan ')' à la ligne 1

Mais je pensais depuis des années que la requête et les données sont envoyées au serveur séparément et jamais interférer. Ainsi j'ai quelques questions (bien que je doute que n'importe qui ait une réponse ...)

  1. Où obtient-il une telle représentation de chaîne familière - a cité et a échappé? Fait-il spécialement pour signaler une erreur ou fait-il partie de la requête?
  2. Comment ça marche en réalité? Substitue-t-il un espace réservé avec des données ou non?
  3. Existe-t-il un moyen d'obtenir une requête complète, et pas seulement un petit peu, à des fins de débogage?

Mise à jour

mysqli le fait comme prévu: il renvoie une erreur dit near 'INN(?,?)'

+0

@DrColossos a la réponse, @Cassy a l'explication. –

Répondre

7

essayer d'ajouter

$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 

;)

+0

Bingo! J'étais sur le point d'écrire une autre mise à jour, exactement sur ce sujet, pointant vers le deuxième paragraphe sur cette page de manuel http://php.net/manual/en/ref.pdo-mysql.php et demander s'il y a un moyen de tester quel est le mode. Juste testé votre code et cela a fonctionné. pas de chaîne échappée dans le message d'erreur –

+0

vous avez effectivement résolu mon autre question aussi :) –

7

Je ne suis pas sûr de tous les détails, mais je vais essayer de répondre.

  1. La citation se produit du côté de la base de données. La base de données échappe et assainit toutes les valeurs (voir puce 2) qu'elle reçoit afin qu'elle soit interprétée correctement. Au moment où l'erreur est levée, la base de données (dans ce cas MySQL) imprime la requête qu'elle a tenté d'exécuter. Ce ne serait pas si utile si elle montre juste la partie préparée.

  2. Non, ce n'est pas le cas. Au moment de la préparation, la requête est compilée côté serveur. Lorsqu'une requête est exécutée avec des valeurs, seules les valeurs sont transmises. C'est à peu près la même chose que d'appeler directement PREPARE et EXECUTE sur la base de données.

  3. Cela dépend de la base de données que vous utilisez. MySQL par exemple peut consigner toutes les requêtes dans un fichier journal (vérifiez les paramètres my.cnf pour cela). Mais vous pouvez également utiliser debugDumpParams() sur le côté PHP.

J'espère que c'était un peu utile.

+0

Merci pour la réponse sensible. Je ne peux pas lier 1 et 2 ensemble. Est-ce que ça veut dire qu'à la fin c'est la même chose que citer/s'échapper mais juste fait du coté serveur? –

+1

+1 pour répondre à la ou les questions réelles et ne pas se concentrer sur la chose IN/INN.puisque la première phrase explique que l'erreur de syntaxe est * intentionnelle * – Jake

+0

@Col. Shrapnel: Pour la base de données 1 et 2 sont deux commandes distinctes. Le premier "enregistre" une requête (métaphoriquement comme une fonction si vous le souhaitez), la seconde lui transmet des paramètres. Dans cette approche, la base de données sait exactement quelle partie de la requête elle peut/doit/devrait citer. Il ne pouvait pas le faire sur une requête combinée. –

Questions connexes