为何低价优惠触发的用户积分更新未生效?技术求助
问题分析与修复方案
核心问题总结
积分无法增加的根源是条件判断逻辑错误、SQL语法/拼接问题,还有一处积分数值错误,同时缺少错误排查机制。以下是具体问题点和修复步骤:
1. 条件判断逻辑错误
当前用isset($row['字段名'])作为更新积分的触发条件,但这个判断只检查查询是否返回结果,不管价格是否真的满足“更低”的规则。正确逻辑应该是判断字段值是否为1(MySQL中布尔比较的结果,true对应1,false对应0)。
2. SQL语法与注入风险
- 字符串拼接时错误使用转义双引号
\",应替换为单引号,或更安全的预处理语句避免SQL注入; - 直接拼接
$prodname、$price和$_SESSION['user']['id']存在严重的SQL注入风险。
3. 积分数值错误
第二个函数中,score_this_month错误地加了50,应和total_score保持一致加20。
4. 缺乏错误处理
执行mysqli_query后未检查执行结果,无法排查更新失败的具体原因(比如用户ID不存在、数据库连接异常等)。
修复后的代码
function check_if_offer_cheaper_with_twenty_than_previous_day($prodname, $price) // 检查用户找到的价格是否比前一日最新可用平均价格低20% { global $db; // 使用预处理语句避免SQL注入 $threshold = $price / 0.8; $sql = "SELECT AVG(price) > ? AS cheaper_than_previous_day FROM prices WHERE prodname = ? AND date = CURDATE() - INTERVAL 1 DAY"; $stmt = mysqli_prepare($db, $sql); mysqli_stmt_bind_param($stmt, "ds", $threshold, $prodname); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $row = mysqli_fetch_assoc($result); // 判断是否满足降价条件,而非仅检查字段是否存在 if ($row && $row['cheaper_than_previous_day'] == 1) { $userId = $_SESSION['user']['id'] ?? 0; if ($userId) { $updateSql = "UPDATE users SET total_score = total_score +50, score_this_month = score_this_month +50 WHERE id = ?"; $updateStmt = mysqli_prepare($db, $updateSql); mysqli_stmt_bind_param($updateStmt, "i", $userId); // 记录更新失败日志 if (!mysqli_stmt_execute($updateStmt)) { error_log("积分更新失败:" . mysqli_error($db)); } } return true; } return false; } function check_if_offer_cheaper_with_twenty_than_previous_week($prodname, $price) // 检查用户找到的价格是否比上周最新可用平均价格低20% { global $db; $threshold = $price / 0.8; $sql = "SELECT AVG(price) > ? AS cheaper_than_previous_week FROM prices WHERE prodname = ? AND date BETWEEN CURDATE() - INTERVAL 8 DAY AND CURDATE() - INTERVAL 1 DAY"; $stmt = mysqli_prepare($db, $sql); mysqli_stmt_bind_param($stmt, "ds", $threshold, $prodname); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $row = mysqli_fetch_assoc($result); if ($row && $row['cheaper_than_previous_week'] == 1) { $userId = $_SESSION['user']['id'] ?? 0; if ($userId) { $updateSql = "UPDATE users SET total_score = total_score +20, score_this_month = score_this_month +20 WHERE id = ?"; $updateStmt = mysqli_prepare($db, $updateSql); mysqli_stmt_bind_param($updateStmt, "i", $userId); if (!mysqli_stmt_execute($updateStmt)) { error_log("积分更新失败:" . mysqli_error($db)); } } return true; } return false; }
额外排查建议
- 验证
$_SESSION['user']['id']是否正确获取,可通过var_dump($_SESSION['user'])打印确认; - 检查
users表的id字段类型是否为整数,避免字符串匹配失败; - 查看服务器错误日志,通过
error_log记录的信息定位具体SQL执行问题。
内容的提问来源于stack exchange,提问作者David Delgado
相关产品推荐
相关产品推荐

