本文目录导读:

在 PHP 中,“预编译”主要指的是 预处理语句,通常用于数据库操作(尤其是 MySQL 和 PostgreSQL),它能有效防止 SQL 注入,并提升重复查询的性能。
以下是 PHP 中实现预编译的两种主流方式:
使用 PDO(PHP Data Objects,推荐)
PDO 提供了统一的接口来访问多种数据库。
基本步骤:
<?php
// 1. 创建数据库连接
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8mb4';
$user = 'root';
$password = '';
try {
$pdo = new PDO($dsn, $user, $password);
// 设置错误模式为异常
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die('数据库连接失败: ' . $e->getMessage());
}
// 2. 准备 SQL 语句(使用占位符 :name 或 ?)
$sql = "SELECT * FROM users WHERE email = :email AND status = :status";
// 或者使用 ? 占位符: $sql = "SELECT * FROM users WHERE email = ? AND status = ?";
$stmt = $pdo->prepare($sql);
// 3. 绑定参数并执行
$email = 'user@example.com';
$status = 'active';
$stmt->execute([
':email' => $email,
':status' => $status
]);
// 如果用 ? 占位符: $stmt->execute([$email, $status]);
// 4. 获取结果
$user = $stmt->fetch(PDO::FETCH_ASSOC);
print_r($user);
?>
关键点:
prepare()方法将 SQL 模板发送给数据库引擎进行编译(预编译)。execute()仅传入具体参数值,数据库引擎直接执行已编译的语句。- 参数值被自动转义,有效防止 SQL 注入。
使用 MySQLi(MySQL Improved Extension)
MySQLi 是 PHP 专门为 MySQL 数据库提供的扩展。
面向对象风格:
<?php
// 1. 创建连接
$mysqli = new mysqli('localhost', 'root', '', 'testdb');
if ($mysqli->connect_error) {
die('连接失败: ' . $mysqli->connect_error);
}
// 2. 准备 SQL 语句(使用 ? 占位符)
$sql = "SELECT * FROM users WHERE email = ? AND status = ?";
$stmt = $mysqli->prepare($sql);
if (!$stmt) {
die('准备失败: ' . $mysqli->error);
}
// 3. 绑定参数("ss" 表示两个字符串参数)
$email = 'user@example.com';
$status = 'active';
$stmt->bind_param("ss", $email, $status);
// 4. 执行
$stmt->execute();
// 5. 获取结果
$result = $stmt->get_result();
$user = $result->fetch_assoc();
print_r($user);
// 6. 关闭语句和连接
$stmt->close();
$mysqli->close();
?>
重要提示:
bind_param()的第一个参数是类型描述符:s(字符串)、i(整数)、d(浮点数)、b(二进制数据)。- MySQLi 只支持 MySQL,而 PDO 支持多种数据库。
相比之下:普通 SQL 拼接(危险!)
// 绝对不要这样做! $sql = "SELECT * FROM users WHERE email = '$email'"; // 极易受 SQL 注入攻击
选择建议
| 特性 | PDO | MySQLi |
|---|---|---|
| 数据库支持 | 12+ 种(MySQL、PostgreSQL、SQLite 等) | 仅 MySQL |
| 面向对象 | 是 | 是(也支持过程式) |
| 命名占位符 | 支持 name 和 |
仅支持 |
| 安全性 | 高(自动转义) | 高(自动转义) |
| 推荐度 | ⭐⭐⭐⭐⭐ 强烈推荐 | ⭐⭐⭐(适合仅用 MySQL 的老项目) |
最佳实践: 新项目建议使用 PDO,因为它更灵活、抽象程度更高,且能轻松切换数据库,两者都实现了 SQL 预编译,但 PDO 是更现代、更推荐的选择。