You need to enable JavaScript to run this app. PHP实现登录次数统计时多次登录后Login_Times不递增问题
优惠活动
大模型
产品
解决方案
定价
更多

PHP实现登录次数统计时多次登录后Login_Times不递增问题

问题根因
  • 核心流程缺失:代码中的SELECT查询从未被实际执行。仅将SQL字符串赋值给$GetLoginTimes,未调用mysqli_query()将查询发送到数据库获取结果集,就直接把字符串传入mysqli_fetch_array()。此时函数因接收的参数不是合法结果集返回NULL,NULL参与+1运算的结果固定为1,因此无论用户第几次登录,计算出的新登录次数永远是1,更新操作只会反复把字段值设置为1,无法完成递增。这也对应了你观察到的现象:首次登录时因为字段初始值一般为0,被代码赋值为1看起来符合预期,后续登录时永远被赋值为1,就不会出现数值递增。
  • 取值逻辑错误:即便SELECT查询被正常执行,mysqli_fetch_array()返回的是关联/索引数组类型的结果行,不是直接的字段标量值,直接对数组执行加法运算会触发PHP语法警告,且数组强制转换为数值的结果固定为1,同样会导致计算结果恒定。
  • 额外隐患:先查再更新的逻辑在高并发场景下,会因多个请求同时读取到相同的旧值,导致登录次数统计不准;同时直接拼接用户输入的邮箱字段到SQL语句中,存在SQL注入风险。
修复方案

推荐实现方式

无需单独查询当前登录次数,直接利用数据库的原子自增操作完成更新,单条SQL即可覆盖需求,同时解决上述代码bug和并发计数不准的问题:

// 使用预处理语句绑定参数,避免SQL注入,执行原子自增更新
$stmt = $con->prepare("UPDATE usertable SET Login_Times = Login_Times + 1 WHERE email = ?");
$stmt->bind_param("s", $email);
$stmt->execute();

如果业务逻辑需要读取更新后的登录次数,可在自增执行完成后再单独查询,无需沿用“先查值、计算新值、再更新”的三段式逻辑。

兼容原有逻辑的修正写法(不推荐)

如果必须保留原有流程,需要补全缺失的查询执行步骤、修正取值方式、做好参数转义:

// 1. 执行SELECT查询获取结果集
$getTimesSql = "SELECT Login_Times FROM usertable WHERE email = ?";
$stmt = $con->prepare($getTimesSql);
$stmt->bind_param("s", $email);
$stmt->execute();
$result = $stmt->get_result();
$userRow = $result->fetch_assoc();
// 2. 从返回的数组中取出真实字段值参与运算
$newLoginTimes = $userRow['Login_Times'] + 1;
// 3. 执行更新操作
$updateSql = "UPDATE usertable SET Login_Times = ? WHERE email = ?";
$stmt2 = $con->prepare($updateSql);
$stmt2->bind_param("is", $newLoginTimes, $email);
$stmt2->execute();

注意:这种写法在多请求并发场景下,很容易因多个请求同时读取到相同的旧登录次数,导致计数更新偏差,优先选择数据库原子自增的实现方式。

内容的提问来源于stack exchange,提问作者Bebo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 17:36:03