本文目录导读:

在 PHP 中连接数据库,最主流、最推荐的方式是 PDO(PHP Data Objects)。
如果非要给出一个明确的结论:首选 PDO,并且搭配预处理语句(Prepared Statements)。
以下是详细的对比分析,帮助你理解为什么选它,以及不同场景下的权衡:
三大主流方式对比
| 特性 | PDO (推荐) | MySQLi (面向过程/面向对象) | **旧版 mysql_*** (已废弃) |
|---|---|---|---|
| 数据库支持 | 支持 12+ 种数据库(MySQL,PostgreSQL,SQLite,Oracle 等) | 仅支持 MySQL | 仅支持 MySQL |
| 安全性 | 高,强制支持预处理语句,有效防 SQL 注入 | 中/高,支持预处理,但需手动注意 API 混用 | 极低,几乎无防注入能力 |
| API 风格 | 统一面向对象 | 面向过程 + 面向对象(混搭) | 面向过程 |
| 错误处理 | 异常(Exception)机制,便于集中捕获 | 警告(Warning)或异常(可选) | 警告(Warning) |
| 性能 | 性能优异,尤其是预处理语句复用场景 | 性能优异 | 性能差 |
| 当前状态 | PHP 官方长期支持 | PHP 5.5+ 推荐,PHP 8.x 仍可用 | PHP 7.0 已彻底移除 |
为什么首选 PDO?
- 安全性(最关键):
PDO 的
prepare()方法将 SQL 语句和参数分离,由数据库驱动处理参数转义,这是目前防止 SQL 注入最有效、最直接的手段,只要你使用预处理语句,几乎不可能被注入。 - 可移植性(灵活性): 如果你的项目后期需要从 MySQL 迁移到 PostgreSQL 或 SQLite,PDO 只需要更改 DSN(数据源名称)和少量驱动配置,核心 SQL 代码基本不用大改,MySQLi 则必须重写全部数据库访问层。
- 统一的 API:
无论你连接哪种数据库,使用的都是同一套
PDO对象、prepare()、execute()方法,学习成本低,代码风格统一。 - 异常处理机制:
PDO 默认支持抛异常(Exception),这意味着你可以用
try-catch包裹数据库操作,一旦出错立即停止并跳转到错误处理逻辑,而不用每执行一句 SQL 就检查一次if (!result)返回值。
什么时候考虑 MySQLi?
虽然 PDO 是通用首选,但在以下少数情况下,MySQLi 也有其优势:
- 项目已经用 MySQLi 写好,短期内不重构:改动成本高,没必要冒风险全量替换。
- 你只需要连接 MySQL,且代码非常古老,对 PHP 8 向下兼容:MySQLi 在 PHP 8 中依然稳健。
- 需要 MySQL 特有的函数:
mysqli_multi_query()(执行多条 SQL 语句)或mysqli_insert_id()(获取自增 ID),PDO 目前没有直接的multi_query支持,需要逐条执行。
最佳实践示例(PDO 标准写法)
这是当前 PHP 社区公认的“标准姿势”,强烈建议直接复制使用:
<?php
// 1. 数据库配置
$host = '127.0.0.1';
$dbname = 'your_database';
$user = 'root';
$pass = 'password';
$charset = 'utf8mb4'; // 强烈建议使用 utf8mb4,支持 emoji 和更多特殊字符
// 2. DSN (数据源名称)
$dsn = "mysql:host=$host;dbname=$dbname;charset=$charset";
// 3. PDO 选项配置(重要!)
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 抛出异常
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 默认返回关联数组
PDO::ATTR_EMULATE_PREPARES => false, // 使用真正的预处理,而非模拟(进一步防注入)
];
try {
// 4. 建立连接
$pdo = new PDO($dsn, $user, $pass, $options);
// 5. 使用预处理语句(安全插入)
$sql = "INSERT INTO users (name, email) VALUES (?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute(['张三', 'zhangsan@example.com']);
echo "插入成功,ID: " . $pdo->lastInsertId();
// 6. 安全查询
$searchId = 1;
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$searchId]);
$user = $stmt->fetch();
// 7. 关闭连接(PDO 会自动关闭,但显式置空有助于释放)
$pdo = null;
} catch (PDOException $e) {
// 记录日志,而不是直接输出给用户看
error_log('Database error: ' . $e->getMessage());
die('数据库连接失败,请稍后再试。');
}
核心结论
- 日常开发(新建项目、框架开发、学习):选 PDO,这是现代 PHP 的标准和趋势。
- 接手老项目(遗留代码):如果项目仍使用 MySQLi,你可以继续维护,但如果要新增功能模块,建议直接使用 PDO 过渡。
- 性能对比:在 PHP 8 环境下,两者执行速度差异极小,几乎可以忽略不计,安全性远比那几毫秒的性能差更重要。
一句话总结:除非你到了必须用 MySQLi 的特殊情况,否则请无脑选择 PDO + 预处理。 如果你是在使用 Laravel、Symfony、ThinkPHP 等框架,它们底层都是基于 PDO 封装的,这也从侧面证明了 PDO 的可靠性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播