PHP连接MySQL数据库教程:PDO用法、预处理语句与异常处理

PHP 连接 MySQL 是后端开发的基础能力。无论是用户系统、文章系统、订单系统还是后台管理,都离不开数据库读写。相比早期的 mysql 扩展,现在更推荐使用 PDO 连接数据库。

PDO 支持多种数据库,提供统一接口,也支持预处理语句和异常处理。本文从连接 MySQL 开始,讲清 PDO 的基础用法、查询数据、写入数据、预处理语句和常见错误处理。

准备数据库信息

连接 MySQL 前,需要准备主机地址、数据库名、用户名、密码和字符集。常见配置包括 hostdbnamecharset

$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 让查询结果默认返回关联数组。

PHP连接MySQL教程配图:PDO数据库连接与预处理语句
PDO 连接数据库时,预处理语句和异常处理是安全与稳定的关键。

捕获连接异常

数据库连接可能失败,比如账号密码错误、数据库不存在、端口不通、权限不足。应该使用 try...catch 捕获异常。

try {
  $pdo = new PDO($dsn, $user, $password, $options);
} catch (PDOException $e) {
  exit('数据库连接失败');
}

生产环境不要把完整异常信息直接输出给用户,否则可能泄露数据库地址、表名或路径。详细错误应写入日志。

查询一条数据

查询单条数据可以使用 prepareexecute,再通过 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 不只是“连上能查”。真正稳定的写法,是连接配置清晰、查询使用预处理、错误有日志、事务有边界、安全有兜底。

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容