- 在PHP中,防止SQL注入的最全面方法是使用预处理语句(prepared statements)结合绑定参数。预处理语句将SQL语句和参数分开,这样即使用户输入恶意数据,也不会影响数据库结构。
以下是使用PDO(PHP Data Objects)扩展的示例代码:
try {
// 创建PDO实例
$pdo = new PDO('mysql:host=your_host;dbname=your_db', 'username', 'password');
// 设置错误模式为异常
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 开始事务
$pdo->beginTransaction();
// 预处理SQL语句
$stmt=$pdo->prepare("SELECT * FROM users
WHERE username = :username AND password = :password");
// 绑定参数
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
// 赋值
$username = 'user_input_username';
$password = 'user_input_password';
// 执行查询
$stmt->execute();
// 获取结果
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 提交事务
$pdo->commit();
// 处理结果
foreach ($result as $row) {
// ...
}
} catch (PDOException $e) {
// 回滚事务
$pdo->rollBack();
// 处理异常
echo "Error: " . $e->getMessage();
}
- 字符串转义
在将用户输入数据存储到数据库之前,需要使用转义函数对字符串进行转义。在PHP中,mysql_real_escape_string()和mysqli_real_escape_string()函数可以实现转义。这种方法是一种低级的防范措施,建议结合其他更安全的防护措施一起使用。
代码示例:
//获取用户输入
$username = $_POST['username'];
$password = $_POST['password'];
//转义字符串
$username = mysql_real_escape_string($username);
$password = mysql_real_escape_string($password);
//准备SQL,然后查询
$sql = "SELECT * FROM users
WHERE username = '$username' AND password = '$password'";
mysql_query($sql);
- 接收数据检测
在接收数据时,根据字段类型设置对应类型数据检测,例如,如果查询的参数是一个数字,可以使用is_numeric()函数来检查它是否是一个数字。如果查询的参数是一个字符串,可以使用ctype_alpha()函数来检查它是否只包含字母。
//对接收数据进行检查
if (is_numeric($_GET['id'])) {
$id = $_GET['id'];
//查询数据库
$sql = "SELECT * FROM users WHERE id = $id";
mysql_query($sql);
}
总结:
-
永远不要相信用户输入的数据。验证用户输入数据的类型、长度、格式等,以避免攻击者使用非法字符或恶意代码来攻击您的应用程序。
-
使用PDO或mysqli扩展库中提供的预处理语句和绑定变量来执行SQL查询。
-
不要在数据库查询中使用拼接字符串的方式来构造SQL查询语句,这样很容易被攻击者利用。
-
对于PHP应用程序中的用户输入,可以通过使用filter_input()函数来过滤和验证数据。
-
禁用PHP的magic_quotes_gpc配置选项,以避免自动添加反斜杠导致的问题。
-
如果您不需要在SQL查询中使用通配符,请避免使用LIKE操作符。LIKE操作符在模式匹配时容易被攻击者利用。