Lors de l'utilisation de PDO pour accéder à la base de données MySQL, les véritables instructions préparées ne sont pas utilisées par défaut. Pour résoudre ce problème, vous devez désactiver les effets d'émulation des instructions préparées. Voici un exemple de création d'un lien utilisant PDO :
Le code est le suivant :
$dbh = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass'); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
setAttribute() Cette ligne est obligatoire et elle indique à PDO de désactiver l'émulation des instructions préparées et d'utiliser de véritables instructions préparées. Cela garantit que l'instruction SQL et les valeurs correspondantes ne sont pas analysées par PHP avant d'être transmises au serveur mysql (désactivant toutes les attaques malveillantes possibles par injection SQL). Bien que vous puissiez définir l'attribut de jeu de caractères (charset=utf8) dans le fichier de configuration, il est important de noter que l'ancienne version de PHP (< 5.3.6) ignore le paramètre de caractère dans le DSN.
Jetons un coup d'œil à un exemple complet d'utilisation de code :
Le code est le suivant :
$dbh = new PDO("mysql:host=localhost; dbname=dbtest", "user", "pass"); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //禁用prepared statements的仿真效果 $dbh->exec("set names 'utf8'"); $sql="select * from test where name = ? and password = ?"; $stmt = $dbh->prepare($sql); $exeres = $stmt->execute(array($testname, $pass)); if ($exeres) { while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { print_r($row); } } $dbh = null;
Ci-dessus Ce code peut empêcher l’injection SQL. Pourquoi?
Lorsque prepare() est appelé, l'instruction de requête a été envoyée au serveur de base de données. À ce moment, seul l'espace réservé est envoyé, et aucun utilisateur ? -les données soumises sont envoyées ; Lorsque execute() est appelé, les valeurs soumises par l'utilisateur seront transmises à la base de données. Les deux sont indépendantes et les attaquants SQL n'ont aucune chance.
Mais ce à quoi nous devons prêter attention, ce sont les situations suivantes. PDO ne peut pas vous aider à empêcher l'injection SQL
1 Vous ne pouvez pas laisser un espace réservé remplacer un ensemble de valeurs. , tel que :
Le code est le suivant :
SELECT * FROM blog WHERE userid IN ( ? );
2 Vous ne pouvez pas laisser des espaces réservés remplacer le nom de la table de données ou le nom de la colonne, tels que : <. 🎜>
SELECT * FROM blog ORDER BY ?;
3 Vous ne pouvez pas laisser l'espace réservé remplacer une autre syntaxe SQL, telle que :
SELECT EXTRACT( ? FROM datetime_column) AS variable_datetime_element FROM blog;