MySQL预处理语句

预处理语句对于防止MySQL注入是非常有用的

预处理语句及绑定参数

预处理语句用于执行多个相同的SQL语句,并且执行效率更高

工作原理

  1. 预处理:创建SQL语句模板并发送到数据库。预留的值使用参数”?”标记
    1
    INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)
  2. 数据库解析,编译,对SQL语句模板执行查询优化,并存储结果不输出

  3. 执行,最后将应用绑定的值传递给参数”?”,数据库执行语句。应用可以多次执行语句,如果参数的值不一样。相比于直接执行SQL语句,预处理语句有几个主要优点

预处理语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";

// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);

// 检测连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}

// 预处理及绑定
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);

// 设置参数并执行
$firstname = "John";
$lastname = "Doe";
$email = "john@example.com";
$stmt->execute();

$firstname = "Mary";
$lastname = "Moe";
$email = "mary@example.com";
$stmt->execute();

$firstname = "Julie";
$lastname = "Dooley";
$email = "julie@example.com";
$stmt->execute();

echo "新记录插入成功";

$stmt->close();
$conn->close();

运行结果

1
新记录插入成功

可以看到之前的步骤没变过

1
INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)

使用了问好,来作为标记参数,可以为整形,字符串,浮点数和布尔值

1
$stmt->bind_param("sss", $firstname, $lastname, $email);

该函数绑定了参数,并使用sss告诉数据类型为字符串

总结

  1. 预处理语句大大降低了分析时间,只做了一次查询;

  2. 绑定参数减少了服务器宽带,只需要发送查询的参数,而不是整个语句;

  3. 预处理语句针对SQL注入非常有用,因为参数值发送后使用不同的协议,保证数据的合法性

  4. 通过告诉数据库参数的数据类型,可以降低 SQL 注入的风险

  5. prepare()方法用于向数据库传预定义语句;bind_param()方法用于绑定预定义语句的参数