如何使用PHP显示数据库事务执行过程中的错误信息
代码问题及修复方案
核心错误点
- 语法错误:catch块中不应该在echo语句里使用
throw关键字,throw是用来抛出异常的指令,无法作为字符串拼接的内容使用,直接删掉即可输出异常信息。 - 数据库异常未开启:mysqli默认不抛出异常,出错只会返回false值,不会进入catch分支,需要手动开启异常上报模式。
- 缺少必填字段校验逻辑:代码没有提前校验用户提交的参数是否完整,空值只会触发数据库字段非空约束报错,无法返回用户易懂的错误提示。
- 多余的query调用:
$connection->query($stmt->execute());写法错误,预编译语句执行直接调用execute()即可,不需要再嵌套query方法。
修复后代码
// 开启mysqli异常上报,让所有数据库错误都会抛出异常进入catch mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); try { // 先做必填参数校验,不满足直接抛出自定义异常 if (empty($_FILES['file']['tmp_name'])) { throw new \Exception("请上传图片文件"); } if (empty($_POST['name']) || empty($_POST['comment'])) { throw new \Exception("姓名和评论为必填项,请填写完整"); } // 可根据业务需求补充更多校验规则,比如邮箱格式、主页格式校验等 $connection->begin_transaction(); $stmt = $connection->prepare("INSERT INTO images (image, mimetype) VALUES (?,?)"); $file = file_get_contents($_FILES['file']['tmp_name']); $mime = $_FILES["file"]["type"]; $stmt->bind_param("ss", $file, $mime); // 去掉多余的query调用 $stmt->execute(); $stmt = $connection->prepare("INSERT INTO form (time, name, homepage, email, comment) VALUES (?, ?, ?, ?, ?)"); $time = date('Y-m-d H:i:s'); $author = $_POST['name']; $homepage = $_POST['homepage'] ?? ''; $email = $_POST['email'] ?? ''; $comment = $_POST['comment']; $stmt->bind_param("sssss", $time, $author, $homepage, $email, $comment); $stmt->execute(); $connection->commit(); echo "提交成功"; } catch (\Exception $e) { $connection->rollback(); // 去掉throw直接输出异常信息 echo "FAILED: " . $e->getMessage(); }
效果说明
- 提前校验用户提交的参数时,会直接返回自定义的易懂错误提示,比如「请上传图片文件」「姓名和评论为必填项,请填写完整」
- 数据库操作出错时也会正常返回具体的错误信息,方便排查问题。
内容的提问来源于stack exchange,提问作者Nilsbergstroom
相关产品推荐
相关产品推荐

