
本文详解如何通过数据库状态校验与 php 逻辑控制,确保每次仅在当前书籍已录入满 5 页后,才允许插入新书记录,杜绝页数不完整时新建书籍的业务违规。
本文详解如何通过数据库状态校验与 php 逻辑控制,确保每次仅在当前书籍已录入满 5 页后,才允许插入新书记录,杜绝页数不完整时新建书籍的业务违规。
在图书管理系统中,若每本书严格限定为 5 页(对应 5 条记录),且所有页必须归属于同一本书(由 jalad 字段标识),则插入逻辑不能仅依赖全局计数,而必须按书分组校验——即:对当前待插入的书名(jalad),检查其在 books 表中已存在的页数;仅当该书页数
✅ 正确的校验逻辑要点
- ❌ 错误做法:SELECT COUNT(x) FROM books WHERE x='$x' —— 此处 x 并非书名字段,且未关联 jalad,导致统计无业务意义;
- ✅ 正确做法:以 jalad 为分组键,查询当前书名已存在的页数,并结合其值做三态判断:
- COUNT(*) == 0 → 全新书籍,允许插入第 1 页;
- 0
- COUNT(*) == 5 → 已满,禁止插入,提示“请先完成当前书籍”;
- COUNT(*) > 5 → 数据异常,应触发告警(正常业务中不应出现)。
? 完整可运行示例代码(含防注入与错误处理)
<?php
// 数据库连接配置(请替换为实际值)
$serverName = "your_server";
$database = "your_db";
$connectionInfo = ["Database" => $database];
$conn = sqlsrv_connect($serverName, $connectionInfo);
if (!$conn) {
die("数据库连接失败: " . print_r(sqlsrv_errors(), true));
}
// 获取用户提交的书籍名称(jalad)和页面内容(sanad)
$jalad = trim($_POST['jalad'] ?? '');
$sanad = trim($_POST['sanad'] ?? '');
if (empty($jalad) || empty($sanad)) {
die("错误:书籍名称(jalad)和页面内容(sanad)均为必填项。");
}
// 【关键】查询该书名当前已录入的页数(使用参数化查询防 SQL 注入)
$sql = "SELECT COUNT(*) AS page_count FROM books WHERE jalad = ?";
$params = [$jalad];
$stmt = sqlsrv_query($conn, $sql, $params);
if (!$stmt) {
die("查询失败: " . print_r(sqlsrv_errors(), true));
}
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
$pageCount = (int)$row['page_count'];
// 三态业务逻辑判断
if ($pageCount == 0) {
// ✅ 全新书籍:插入第 1 页
$insertSql = "INSERT INTO books (jalad, sanad) VALUES (?, ?)";
$insertParams = [$jalad, $sanad];
if (sqlsrv_query($conn, $insertSql, $insertParams)) {
echo "✅ 新书籍《{$jalad}》第 1 页录入成功。";
} else {
echo "❌ 插入失败:" . print_r(sqlsrv_errors(), true);
}
} elseif ($pageCount < 5) {
// ✅ 续录:插入当前书籍的下一页
$insertSql = "INSERT INTO books (jalad, sanad) VALUES (?, ?)";
$insertParams = [$jalad, $sanad];
if (sqlsrv_query($conn, $insertSql, $insertParams)) {
echo "✅ 《{$jalad}》第 " . ($pageCount + 1) . " 页录入成功。";
} else {
echo "❌ 插入失败:" . print_r(sqlsrv_errors(), true);
}
} elseif ($pageCount == 5) {
// ⚠️ 拒绝:已满 5 页
echo "⚠️ 拒绝操作:书籍《{$jalad}》已满 5 页,无法继续添加页面。如需录入新书,请更换书籍名称。";
} else {
// ? 异常:数据不一致(如手动修改导致 >5)
error_log("[ALERT] 书籍 '{$jalad}' 页数异常:{$pageCount} > 5");
echo "❌ 系统异常:书籍页数超出限制,请联系管理员。";
}
sqlsrv_close($conn);
?>⚠️ 关键注意事项
- 永远使用参数化查询:避免直接拼接 $_POST 数据,防止 SQL 注入(原代码中 $x='$x' 极度危险);
- 字段名一致性:确保表结构中主标识字段为 jalad(书名)、内容字段为 sanad(页面),而非代码中误用的 x;
- 事务增强健壮性(进阶):高并发场景下,建议将“查+插”封装在事务中,避免竞态条件(如两个请求同时读到 pageCount=4,均插入第 5 页);
- 前端配合:可在表单中动态禁用“提交”按钮,或通过 AJAX 预检页数状态,提升用户体验;
- 唯一约束(可选):在数据库层面为 (jalad, sanad) 添加唯一索引,防止重复页面误录。
通过以上设计,系统可精准保障“一书五页”的业务规则,既满足数据完整性要求,又具备良好的可维护性与安全性。











