在PHP开发中,经常需要先执行UPDATE修改数据,再执行SELECT获取更新后的结果。如果处理不当,可能出现数据未提交、查询结果陈旧或语句报错等问题。使用PDO扩展配合事务是最稳妥的方案。

为什么不能直接用多语句查询
部分开发者尝试用mysqli_multi_query或PDO的多个语句一次性发送,但这样难以绑定参数,且容易引发SQL注入。更合理的方式是开启事务,分步执行已预处理的语句。
使用PDO执行UPDATE与SELECT
下面示例展示在事务中先更新用户积分,再查询该用户最新积分。所有参数均通过预处理绑定,避免注入风险。
<?php
try {
$pdo = new PDO(
'mysql:host=127.0.0.1;dbname=test;charset=utf8mb4',
'db_user',
'db_pass',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$pdo->beginTransaction();
$update = $pdo->prepare('UPDATE users SET points = points + ? WHERE id = ?');
$update->execute([10, 1]);
$select = $pdo->prepare('SELECT points FROM users WHERE id = ?');
$select->execute([1]);
$row = $select->fetch(PDO::FETCH_ASSOC);
$pdo->commit();
echo '最新积分:' . $row['points'];
} catch (Exception $e) {
if (isset($pdo) && $pdo->inTransaction()) {
$pdo->rollBack();
}
echo '执行失败:' . $e->getMessage();
}
?>
关键点说明
- 使用
beginTransaction确保UPDATE和SELECT在同一事务中,要么都成功要么都回滚。 - UPDATE与SELECT分别用
prepare和execute,参数用问号占位符绑定。 - 捕获异常时判断是否在事务内,避免重复回滚报错。
常见错误对照
| 错误做法 | 正确做法 |
|---|---|
| 字符串拼接SQL | 预处理绑定参数 |
| 不开启事务 | 用beginTransaction包裹 |
| 忽略异常回滚 | catch中rollBack |
小结
在PHP中执行UPDATE加SELECT多条语句,核心是用PDO事务加预处理。这种方式既安全又容易维护,适合绝大多数业务场景。