PHP mysqli实现忠诚度计划:剩余访问次数增减及0值提示问题
解决忠诚度计划的访问次数管理问题
看起来你在搭建一个基于剩余访问次数的忠诚度系统,但目前的代码逻辑有几个关键问题没处理到位,我帮你梳理并给出完整的实现方案:
现有代码的核心问题
- 用
mysqli_affected_rows()判断查询结果是错误的,这个函数是用来统计增删改操作影响的行数,查询操作应该用mysqli_num_rows()来判断是否找到用户记录。 - 存在SQL注入风险,直接把
$id拼进SQL语句里非常危险,容易被恶意利用。 - 逻辑不完整:没有对
balance的值进行判断,也没实现访问后的次数更新逻辑。
完整实现方案
下面是修复后的代码,包含安全查询、余额判断、次数更新和提示逻辑:
<?php // 假设$connection是已经建立好的数据库连接 // 从登录会话获取用户ID(必须是安全渠道,禁止直接用用户提交的参数) session_start(); $id = $_SESSION['user_id'] ?? null; if(isset($_POST['Submit']) && $id) { // 1. 使用预处理语句防止SQL注入 $stmt = mysqli_prepare($connection, "SELECT balance, total FROM countvisits WHERE id = ?"); mysqli_stmt_bind_param($stmt, "i", $id); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); // 2. 判断是否找到用户记录 if(mysqli_num_rows($result) > 0) { $user_data = mysqli_fetch_assoc($result); $current_balance = $user_data['balance']; $current_total = $user_data['total']; if($current_balance > 0) { // 3. 剩余次数充足,允许访问并更新数据 $new_balance = $current_balance - 1; $new_total = $current_total + 1; // 预处理更新语句 $update_stmt = mysqli_prepare($connection, "UPDATE countvisits SET balance = ?, total = ? WHERE id = ?"); mysqli_stmt_bind_param($update_stmt, "iii", $new_balance, $new_total, $id); mysqli_stmt_execute($update_stmt); // 这里可以跳转到访问页面,或者显示成功提示 echo "<script>alert('访问成功!剩余次数:{$new_balance}');</script>"; // header("Location: your_access_page.php"); // exit; } else { // 4. 剩余次数为0,显示提示 echo "<script>alert('您的免费访问次数已用完,请联系管理员或升级会员!');</script>"; } } else { // 用户不存在的处理逻辑 echo "<script>alert('用户不存在!');</script>"; } // 关闭语句和结果集,释放资源 mysqli_stmt_close($stmt); mysqli_free_result($result); } ?>
额外注意事项
- 用户ID的安全性:一定要从登录会话(比如
$_SESSION['user_id'])获取用户ID,绝对不能直接使用用户提交的参数(比如$_GET['id']或$_POST['id']),否则会被恶意篡改。 - 前端提示优化:如果不想用JS弹窗,可以在页面上输出HTML提示信息,比如
<div class="alert alert-warning">您的免费访问次数已用完</div>。 - 错误处理:调试阶段可以添加
mysqli_error()捕获数据库操作错误,方便排查问题,比如:if(!mysqli_stmt_execute($update_stmt)) { echo "更新失败:" . mysqli_error($connection); }
内容的提问来源于stack exchange,提问作者a2zbollywood
相关产品推荐
相关产品推荐

