Maison > base de données > tutoriel mysql > le corps du texte

Comment utiliser PDO pour interroger MySQL afin d'éviter l'injection SQL

jacklove
Libérer: 2018-06-09 14:03:50
original
1682 Les gens l'ont consulté

Lors de l'utilisation des méthodes traditionnelles mysql_connect et mysql_query pour se connecter et interroger la base de données, si le filtrage n'est pas strict, il existe un risque d'injection SQL. Bien que la fonction mysql_real_escape_string() puisse être utilisée pour filtrer les valeurs soumises par l'utilisateur, elle présente également des défauts. En utilisant la méthode de préparation de l'extension PDO de PHP, vous pouvez éviter le risque d'injection SQL.

PDO (PHP Data Object) est une nouvelle fonctionnalité majeure ajoutée à PHP5, car avant PHP 5, php4/php3 disposait de nombreuses extensions de base de données pour se connecter et se connecter à chaque base de données Processing. , tel que php_mysql.dll. PHP6 utilisera également PDO pour se connecter par défaut, et l'extension mysql sera utilisée comme auxiliaire. Adresse officielle : http://php.net/manual/en/book.pdo.php

1. Configuration PDO

Avant d'utiliser l'extension PDO, vous devez d'abord activer cette extension. Dans php.ini, supprimez le ";" devant "extension=php_pdo.dll". pour supprimer le ";" devant l'extension de base de données liée à PDO ";" (généralement php_pdo_mysql.dll est utilisé), puis redémarrez le serveur Apache.

extension=php_pdo.dll 
extension=php_pdo_mysql.dll
Copier après la connexion

2. PDO se connecte à la base de données MySQL

$dbh = new PDO("mysql:host=localhost;dbname=mydb","root","password");
Copier après la connexion

La connexion par défaut n'est pas longue, si vous souhaitez utiliser une connexion longue à la base de données, vous pouvez ajouter les paramètres suivants à la fin :

$dbh = new PDO("mysql:host=localhost;dbname=mydb","root","password","array(PDO::ATTR_PERSISTENT => true) "); 
$dbh = null; //(释放)
Copier après la connexion

3. Propriétés de réglage du PDO

PDO dispose de trois méthodes de gestion des erreurs :

PDO::ERrmODE_SILENT n'affiche pas les informations d'erreur, définit uniquement le code d'erreur

PDO ::ERrmODE_WARNING affiche une erreur d'avertissement

PDO::ERrmODE_EXCEPTION lève une exception

Vous pouvez utiliser l'instruction suivante pour définir la méthode de gestion des erreurs sur lancer une exception

$db->setAttribute(PDO::ATTR_ERrmODE, PDO::ERrmODE_EXCEPTION);
Copier après la connexion

Étant donné que différentes bases de données gèrent différemment la casse des noms de champs renvoyés, PDO fournit l'élément de paramètre PDO::ATTR_CASE (y compris PDO::CASE_LOWER, PDO::CASE_NATURAL , PDO::CASE_UPPER) pour déterminer le nom du champ renvoyé en majuscules et en minuscules.

Spécifiez la valeur correspondante en php pour la valeur NULL renvoyée par la base de données en définissant le type PDO::ATTR_ORACLE_NULLS (y compris PDO::NULL_NATURAL, PDO::NULL_EmpTY_STRING, PDO::NULL_TO_STRING ).

4. Méthodes PDO courantes et leurs applications

PDO::query() est principalement utilisé pour les opérations d'enregistrement. qui renvoient des résultats, en particulier les opérations SELECT

PDO::exec() sont principalement destinés aux opérations qui ne renvoient pas de jeu de résultats, telles que INSERT, UPDATE et d'autres opérations

PDO::prepare() est principalement une opération de prétraitement. Vous devez utiliser $rs->execute() pour exécuter l'instruction SQL dans le prétraitement. Cette méthode peut lier des paramètres et est relativement puissante (. empêcher l'injection SQL Fiez-vous simplement à ceci)

PDO::lastInsertId() renvoie la dernière opération d'insertion, le type de colonne de clé primaire est le dernier ID d'auto-incrémentation

PDOStatement::fetch() est utilisé pour obtenir un enregistrement

PDOStatement::fetchAll() est utilisé pour obtenir tous les jeux d'enregistrements dans une collection

PDOStatement::fetchColumn() est un champ du premier enregistrement spécifié dans le résultat de la récupération. La valeur par défaut est le premier champ

PDOStatement::rowCount. () : principalement utilisé. Le jeu de résultats affecté par les opérations DELETE, INSERT et UPDATE sur PDO::query() et PDO::prepare() n'est pas valide pour la méthode PDO::exec() et l'opération SELECT.


5.Opération PDO Instance de base de données MYSQL

<?php 
$pdo = new PDO("mysql:host=localhost;dbname=mydb","root",""); 
if($pdo -> exec("insert into mytable(name,content) values(&#39;fdipzone&#39;,&#39;123456&#39;)")){ 
echo "insert success"; 
echo $pdo -> lastinsertid(); 
} 
?>
Copier après la connexion
<?php 
$pdo = new PDO("mysql:host=localhost;dbname=mydb","root",""); 
$rs = $pdo -> query("select * from table"); 
$rs->setFetchMode(PDO::FETCH_ASSOC); //关联数组形式
//$rs->setFetchMode(PDO::FETCH_NUM); //数字索引数组形式
while($row = $rs -> fetch()){ 
    print_r($row); 
} 
?>
Copier après la connexion
<?php
foreach( $db->query( "SELECT * FROM table" ) as $row )
{
    print_r( $row );
}
?>
Copier après la connexion

Statistiques Combien y a-t-il de lignes de données :

<?php
$sql="select count(*) from table";
$num = $dbh->query($sql)->fetchColumn();
?>
Copier après la connexion

méthode de préparation :

<?php
$query = $dbh->prepare("select * from table");
if ($query->execute()) {
    while ($row = $query->fetch()) {
        print_r($row);
    }
}
?>
Copier après la connexion

requête paramétrée de préparation :

<?php
$query = $dbh->prepare("select * from table where id = ?");
if ($query->execute(array(1000))) { 
    while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
        print_r($row);
    }
}
?>
Copier après la connexion

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 d'utilisation de PDO pour créer un lien :

<?php
$dbh = new PDO(&#39;mysql:dbname=mydb;host=127.0.0.1;charset=utf8&#39;, &#39;root&#39;, &#39;pass&#39;);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
?>
Copier après la connexion

setAttribute()这一行是强制性的,它会告诉 PDO 禁用模拟预处理语句,并使用 real parepared statements 。这可以确保SQL语句和相应的值在传递到mysql服务器之前是不会被PHP解析的(禁止了所有可能的恶意SQL注入攻击)。

虽然你可以配置文件中设置字符集的属性(charset=utf8),但是需要格外注意的是,老版本的 PHP( < 5.3.6)在DSN中是忽略字符参数的。

完整的代码使用实例:

<?php
$dbh = new PDO("mysql:host=localhost; dbname=mydb", "root", "pass");
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //禁用prepared statements的仿真效果
$dbh->exec("set names &#39;utf8&#39;"); 
$sql="select * from table where username = ? and password = ?";
$query = $dbh->prepare($sql); 
$exeres = $query->execute(array($username, $pass)); 
if ($exeres) { 
    while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
        print_r($row);
    }
}
$dbh = null;
?>
Copier après la connexion

上面这段代码就可以防范sql注入。为什么呢?

当调用 prepare() 时,查询语句已经发送给了数据库服务器,此时只有占位符 ? 发送过去,没有用户提交的数据;当调用到 execute()时,用户提交过来的值才会传送给数据库,它们是分开传送的,两者独立的,SQL攻击者没有一点机会。

但是我们需要注意的是以下几种情况,PDO并不能帮助你防范SQL注入。

不能让占位符 ? 代替一组值,这样只会获取到这组数据的第一个值,如:

select * from table where userid in ( ? );
Copier après la connexion

如果要用in來查找,可以改用find_in_set()实现

$ids = &#39;1,2,3,4,5,6&#39;;
select * from table where find_in_set(userid, ?);
Copier après la connexion

不能让占位符代替数据表名或列名,如:

select * from table order by ?;
Copier après la connexion

不能让占位符 ? 代替任何其他SQL语法,如:

select extract( ? from addtime) as mytime from table;
Copier après la connexion

本篇文章如何使用PDO查询mysql避免SQL注入的方法,更多相关内容请关注php中文网。

相关推荐:

关于php 双向队列类的讲解

php heredoc 与 nowdoc之间的区别与特点

关于HTML5 localStorage and sessionStorage 之间的区别

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!