En PHP avec PDO, Comment vérifier la requête finale paramétrée par SQL? [dupliquer]
cette question a déjà une réponse ici:
en PHP, lorsque vous accédez à la base de données MySQL avec PDO avec une requête paramétrée, Comment Pouvez-vous vérifier la requête finale (après avoir remplacé tous les tokens)?
Est-il un moyen de vérifier ce qui est réellement exécuté par la base de données?
9 réponses
Donc je pense que je vais enfin répondre à ma propre question afin d'avoir une solution complète pour l'enregistrement. Mais je dois remercier Ben James et Kailash Badu qui ont fourni les indices pour cela.
Réponse Courte
, Comme l'a mentionné Ben James: NON .
la requête SQL complète n'existe pas du côté de PHP, parce que la requête-avec-les jetons et les paramètres sont envoyés séparément au la base de données.
Seulement du côté de la base de données la requête complète existe.
même en essayant de créer une fonction pour remplacer les tokens du côté de PHP ne garantirait pas que le processus de remplacement est le même que celui du SQL (des choses délicates comme le type de token, bindValue vs bindParam, ...)
contournement
c'est ici que je développe la réponse de Kailash Badu.
En enregistrant toutes les requêtes SQL, nous pouvons voir ce qui est réellement exécuté sur le serveur.
Avec mySQL, cela peut être fait en mettant à jour le my.cnf (ou mon.ini dans mon cas avec Wamp server), et l'ajout d'une ligne comme:
log=[REPLACE_BY_PATH]/[REPLACE_BY_FILE_NAME]
il suffit de ne pas exécuter cela dans la production!!!
utiliser des instructions préparées avec des valeurs paramétrées n'est pas simplement une autre façon de créer dynamiquement une chaîne de caractères SQL. Vous créez une instruction préparée à la base de données, puis envoyez les valeurs des paramètres seulement.
donc ce qui est probablement envoyé à la base de données sera un PREPARE ...
, puis SET ...
et enfin EXECUTE ...
.
vous ne serez pas en mesure d'obtenir une chaîne SQL comme SELECT * FROM ...
, même si elle produirait des résultats équivalents, parce qu'une telle requête n'a jamais été envoyée à la base de données.
vous pourriez utiliser PDOStatement->debugDumpParams
. Voir la documentation PHP .
je vérifie le journal de requête pour voir la requête exacte qui a été exécutée comme déclaration préparée.
j'ai d'abord évité d'activer la journalisation pour surveiller AOP parce que je pensais que ce serait un problème, mais ce n'est pas difficile du tout. Vous n'avez pas besoin de redémarrer MySQL (après 5.1.9):
Exécuter ce SQL dans phpMyAdmin ou dans tout autre environnement où vous pouvez avoir élevé db privilèges:
SET GLOBAL general_log = 'ON';
dans un terminal, suivez votre fichier journal. Le mien était ici:
>sudo tail -f /usr/local/mysql/data/myMacComputerName.log
vous pouvez rechercher vos fichiers mysql avec ce terminal commande:
>ps auxww|grep [m]ysqld
j'ai trouvé que PDO échappe à tout, donc vous ne pouvez pas écrire
$dynamicField = 'userName';
$sql = "SELECT * FROM `example` WHERE `:field` = :value";
$this->statement = $this->db->prepare($sql);
$this->statement->bindValue(':field', $dynamicField);
$this->statement->bindValue(':value', 'mick');
$this->statement->execute();
parce qu'il crée:
SELECT * FROM `example` WHERE `'userName'` = 'mick' ;
qui n'a pas créé d'erreur, juste un résultat vide. Au lieu de cela, j'ai dû utiliser
$sql = "SELECT * FROM `example` WHERE `$dynamicField` = :value";
pour obtenir
SELECT * FROM `example` WHERE `userName` = 'mick' ;
quand vous avez terminé, exécutez:
SET GLOBAL general_log = 'OFF';
ou vos bûches seront énormes.
Ce que j'ai fait pour imprimer cette requête est un peu compliqué mais ça marche :)
dans la méthode qui assigne des variables à mon énoncé j'ai une autre variable qui ressemble un peu à ceci:
$this->fullStmt = str_replace($column, '\'' . str_replace('\'', '\\'', $param) . '\'', $this->fullStmt);
où:
$column
est-ce que mon jeton
$param
est la valeur réelle attribuée au jeton
$this->fullStmt
est ma déclaration d'impression seulement avec des jetons remplacés
ce qu'il fait est de simplement remplacer les tokens par des valeurs lorsque la véritable affectation AOP se produit.
j'espère que je ne t'ai pas embrouillé et au moins t'ai pointé dans la bonne direction.
la façon la plus facile de le faire est de lire le fichier journal d'exécution mysql et vous pouvez le faire à l'exécution.
il y a une belle explication ici:
Comment afficher les dernières requêtes exécutées sur MySQL?
Je ne crois pas que vous puissiez, même si j'espère que quelqu'un me prouvera que j'ai tort.
je sais que vous pouvez imprimer la requête et sa méthode toString vous montrera le sql sans les remplacements. Cela peut être pratique si vous construisez des chaînes de requête complexes, mais cela ne vous donne pas la requête complète avec des valeurs.
je pense que la façon la plus facile de voir le texte final de requête quand vous utilisez pdo est de faire l'erreur spéciale et regarder le message d'erreur. Je ne sais pas comment faire cela, mais quand je fais une erreur sql dans le cadre de Yii qui utilise pdo, je peux voir le texte de requête