$stmt = $pdo->prepare('select * from user where id=?'); $id = 1; $stmt->bindParam(1,$id); $stmt - >execute();
<span style="font-size:14px;" data-filtered="filtered"></span>
Dans ce cas, PHP envoie simplement l'instruction sql au serveur mysql, C'est ce n'est pas différent de la façon dont nous utilisons habituellement mysql_real_escape_string pour échapper la chaîne, puis la fusionner dans une instruction SQL (elle est simplement échappée par le pilote local PDO. Évidemment, dans ce cas, il est toujours possible de provoquer une injection SQL, c'est-à-dire). disons, en PHP, l'appel local de mysql_real_escape_string dans pdo pour préparer l'exécution de la requête utilise le jeu de caractères local à un octet, et lorsque nous transmettons des variables codées sur plusieurs octets, cela peut toujours provoquer des vulnérabilités d'injection SQL (l'un des problèmes des versions antérieures à PHP 5.3 .6 Tout d'abord, cela explique pourquoi lors de l'utilisation de PDO, il est recommandé de mettre à niveau vers php 5.3.6+ et de spécifier le jeu de caractères dans la chaîne DSN
qui est correct. l'échappement doit consister à spécifier le jeu de caractères pour le serveur mysql et à envoyer la variable au serveur MySQL pour compléter l'échappement des caractères
alors, comment. interdire l'échappement local PHP et laisser le serveur MySQL s'échapper ?
PDO a un paramètre nommé PDO::ATTR_EMULATE_PREPARES, qui indique s'il faut utiliser la préparation de la simulation locale PHP. inconnu. Et selon les résultats de l'analyse de capture de paquets que nous venons de faire, PHP 5.3.6+ utilise toujours des variables locales pour les convertir et les assembler en SQL et les envoyer au serveur MySQL. Nous définissons cette valeur sur false,
.$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);$stmt = $pdo->prepare('select * from user where id=?'); $id = 1; $stmt->bindParam(1,$id); $stmt - >execute();
Cette fois, PHP envoie le modèle SQL et les variables à MySQL en deux fois, et MySQL termine l'échappement des variables puisque les variables et le modèle SQL sont envoyés en deux fois, alors il n'y a pas de SQL. problème d'injection, mais l'attribut charset doit être spécifié dans le DSN, tel que :
$pdo = new PDO('mysql:host=localhost;dbname=test ; charset=utf8', 'root');
Eh bien, il y a un problème, si dans DSN Si le jeu de caractères est spécifié, dois-je toujours exécuter les noms de set <
Oui, il ne peut pas être omis ;charset> >A. Dites au serveur mysql quel encodage le client (programme PHP) lui a soumis
B. Dites au serveur mysql quel est l'encodage du résultat requis par le client
En d'autres termes, si la table de données utilise le jeu de caractères gbk et que le programme PHP utilise l'encodage UTF-8, nous exécutons set names utf8 avant d'exécuter la requête et disons au serveur mysql de l'encoder correctement. Il n'est pas nécessaire de convertir l'encodage dans le programme. De cette façon, nous soumettons la requête au serveur mysql en codage utf-8, et les résultats obtenus seront également en codage utf-8. Cela élimine le problème de l'encodage de conversion dans le programme. N'ayez aucun doute. Cela ne produira pas de code tronqué. Alors, quelle est la fonction de spécifier un jeu de caractères dans DSN ? Il indique simplement à PDO que lorsque le pilote local ? escapes Pour utiliser le jeu de caractères spécifié (et non pour définir le jeu de caractères de communication du serveur MySQL), pour définir le jeu de caractères de communication du serveur MySQL, vous devez également utiliser la commande set names Recommandations associées : Cadre ThinkPHP basé sur un exemple de fonctionnement d'une base de données de connexion en mode PDO
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!