
本文详解如何修复PHP表单提交后因未正确处理MySQL查询结果而导致的“目的地不可用”误报问题,重点讲解mysqli_query()返回值与实际数据获取的区别、SQL注入防护及完整页面响应规范。
本文详解如何修复php表单提交后因未正确处理mysql查询结果而导致的“目的地不可用”误报问题,重点讲解`mysqli_query()`返回值与实际数据获取的区别、sql注入防护及完整页面响应规范。
在您提供的PHP脚本中,核心逻辑意图是:验证表单完整性 → 查询目标国家剩余套餐数 → 若有余量则扣减并提示成功,否则弹出“无可用套餐”警告。但当前代码存在一个关键误解:mysqli_query() 的返回值是查询执行是否成功(布尔值),而非查询结果本身。因此,if($res > 0) 实际判断的是“查询是否执行成功”,而非“是否有可用套餐”,这直接导致即使库存充足,也总进入 $res
✅ 正确做法:获取并检查实际查询结果
必须使用 mysqli_fetch_assoc() 或类似函数从结果集中提取数据。以下是修正后的关键逻辑段(含安全增强):
if (isset($_POST['send'])) {
// 输入验证(基础)
$required = ['name', 'email', 'phone', 'address', 'location', 'guests', 'arrivals', 'leaving'];
$missing = array_filter($required, fn($field) => empty($_POST[$field]));
if (!empty($missing)) {
echo '<script>alert("'.$msg1.'");</script>';
exit;
}
// 使用预处理语句防止SQL注入
$stmt = $connection->prepare("SELECT n_package FROM destination WHERE country = ?");
$stmt->bind_param("s", $_POST['location']);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 0) {
// 目标国家不存在于数据库
echo '<script>alert("Destination not found.");</script>';
} else {
$row = $result->fetch_assoc();
$available = (int)$row['n_package'];
if ($available > 0) {
// 扣减库存
$update = $connection->prepare("UPDATE destination SET n_package = n_package - 1 WHERE country = ?");
$update->bind_param("s", $_POST['location']);
$update->execute();
echo '<script>alert("'.$msg2.'");</script>';
} else {
echo '<script>alert("'.$msg3.'");</script>';
}
}
}
⚠️ 关键注意事项
- 绝不直接拼接用户输入:原始代码中 $location 直接嵌入SQL字符串,极易遭受SQL注入攻击。务必使用预处理语句(prepare() + bind_param())。
- 区分查询执行与数据获取:mysqli_query() 返回资源或布尔值;要读取数据,必须调用 fetch_assoc()、fetch_row() 等方法。
- 完整HTML响应:仅输出 <script> 标签会导致页面空白。生产环境应重定向(如 header('Location: success.php'); exit;)或渲染完整HTML页面,而非依赖内联JS弹窗。</script>
- 空值与类型安全:$row['n_package'] 可能为 NULL,强制转换为 (int) 避免比较异常。
? 总结
错误根源在于混淆了“查询是否成功”与“查询结果是否满足业务条件”。修复的核心是:先执行查询,再显式提取并检验数据值。结合预处理语句与严谨的流程控制,即可确保库存校验逻辑准确可靠,彻底消除误报弹窗。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











