PHP 连接 MySQL 是后端开发的基础能力。无论是用户系统、文章系统、订单系统还是后台管理,都离不开数据库读写。相比早期的 mysql 扩展,现在更推荐使用 PDO 连接数据库。
PDO 支持多种数据库,提供统一接口,也支持预处理语句和异常处理。本文从连接 MySQL 开始,讲清 PDO 的基础用法、查询数据、写入数据、预处理语句和常见错误处理。
准备数据库信息
连接 MySQL 前,需要准备主机地址、数据库名、用户名、密码和字符集。常见配置包括 host、dbname、charset。
$host = '127.0.0.1';
$dbname = 'demo';
$user = 'root';
$password = 'password';
$charset = 'utf8mb4';
线上环境不要把数据库密码直接写死在公开代码里,建议放在配置文件或环境变量中,并做好访问权限控制。
创建 PDO 连接
PDO 连接 MySQL 时,需要构造 DSN 字符串,并传入用户名、密码和配置选项。
$dsn = "mysql:host=$host;dbname=$dbname;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new PDO($dsn, $user, $password, $options);
PDO::ERRMODE_EXCEPTION 可以让数据库错误以异常形式抛出,便于统一捕获。PDO::FETCH_ASSOC 让查询结果默认返回关联数组。

捕获连接异常
数据库连接可能失败,比如账号密码错误、数据库不存在、端口不通、权限不足。应该使用 try...catch 捕获异常。
try {
$pdo = new PDO($dsn, $user, $password, $options);
} catch (PDOException $e) {
exit('数据库连接失败');
}
生产环境不要把完整异常信息直接输出给用户,否则可能泄露数据库地址、表名或路径。详细错误应写入日志。
查询一条数据
查询单条数据可以使用 prepare 和 execute,再通过 fetch 获取结果。
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);
$user = $stmt->fetch();
使用占位符可以避免把用户输入直接拼进 SQL。即使只是数字 ID,也建议使用预处理。
查询多条数据
查询多条数据时,可以使用 fetchAll。
$stmt = $pdo->prepare('SELECT * FROM articles WHERE status = ? ORDER BY id DESC');
$stmt->execute(['published']);
$articles = $stmt->fetchAll();
如果数据量很大,不建议一次性 fetchAll 全部数据,应该使用分页或逐行读取,避免内存占用过高。
命名占位符
除了问号占位符,PDO 也支持命名占位符。命名占位符在字段较多时可读性更好。
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute([
'email' => $email
]);
命名占位符适合复杂查询,尤其是多个条件组合时,代码更容易维护。
插入数据
插入数据同样应该使用预处理语句。
$stmt = $pdo->prepare(
'INSERT INTO users (username, email) VALUES (:username, :email)'
);
$stmt->execute([
'username' => $username,
'email' => $email
]);
插入成功后,如果需要获取自增 ID,可以使用 lastInsertId()。
$id = $pdo->lastInsertId();
更新和删除
更新和删除也要使用预处理,并注意条件是否正确。没有 WHERE 条件的更新或删除非常危险。
$stmt = $pdo->prepare('UPDATE users SET email = :email WHERE id = :id');
$stmt->execute([
'email' => $email,
'id' => $id
]);
执行后可以通过 rowCount() 查看受影响行数,但不同数据库场景下返回值行为可能略有差异。
事务处理
当多个数据库操作必须同时成功或同时失败时,应使用事务。比如创建订单和扣减库存,就不能只成功其中一步。
try {
$pdo->beginTransaction();
// 执行多条 SQL
$pdo->commit();
} catch (Throwable $e) {
$pdo->rollBack();
throw $e;
}
事务能保证数据一致性。涉及资金、库存、订单状态等场景,一定要认真设计事务边界。
常见异常
常见数据库异常包括连接失败、SQL 语法错误、字段不存在、唯一索引冲突、权限不足、连接超时等。开发环境可以显示详细信息,生产环境应记录日志并返回友好提示。
不要把 $e->getMessage() 直接展示给普通用户。错误详情属于内部信息,应该进入日志系统。
安全注意事项
预处理语句可以防 SQL 注入,但它不是全部安全措施。字段白名单、权限控制、输入校验、输出转义、数据库账号最小权限同样重要。
比如排序字段、表名、列名通常不能作为普通参数绑定。如果它们来自用户输入,必须使用白名单判断,不能直接拼接。
常见错误
第一种错误是拼接 SQL 字符串。第二种错误是数据库连接异常直接输出给用户。第三种错误是忘记设置字符集,导致中文乱码。第四种错误是一次性读取大量数据。第五种错误是线上数据库账号权限过大。
实践建议
实际项目中,可以把 PDO 连接封装成公共函数或数据库类,统一设置错误模式、字符集和默认 fetch 模式。所有带用户输入的 SQL 都使用预处理语句,所有异常都进入日志,不直接暴露给用户。
PHP 连接 MySQL 不只是“连上能查”。真正稳定的写法,是连接配置清晰、查询使用预处理、错误有日志、事务有边界、安全有兜底。














暂无评论内容