You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter4点赞点踩功能:如何限制单用户仅可投一票

问题根因

现有代码存在3处逻辑缺陷,导致点赞、点踩可同时生效:

  • 执行点踩逻辑时,仅判断用户是否已点赞,未清除用户对同一张图片已存在的点踩记录;执行点赞逻辑时同理,未清除已存在的点赞记录,会直接生成两条独立的投票记录
  • 取消点赞、取消点踩的删除语句缺失username、viewkey过滤条件,执行时会删除整张action表中对应类型的所有记录,属于严重逻辑漏洞
  • 代码中unset($image->setUserLiked)、unset($image->userDisliked)属于无效写法,unset仅可删除对象属性,无法删除对象方法,不过该问题不影响核心投票逻辑,仅会产生冗余代码和PHP运行警告。
修复代码

核心调整思路:用户对单张图片的点赞/点踩记录最多仅保留1条,执行新的投票操作前先清空同用户同图片下的所有历史赞/踩记录,所有删除、更新操作必须补全用户、图片维度的过滤条件,避免误操作全表数据。
将原switch语句中dislike、undislike、like、unlike四个分支替换为以下代码即可:

case 'dislike':
    $username = session()->get('username');
    $viewkey = $request['viewkey'];
    // 清除当前用户对该图片的所有历史赞/踩记录
    $this->builder()
        ->whereIn('action', [0, 1])
        ->where(['username' => $username, 'viewkey' => $viewkey])
        ->delete();
    // 写入新的点踩记录
    $this->builder()->insert([
        'action'      => 0,
        'username'    => $username,
        'viewkey'     => $viewkey,
        'modified_at' => $request['modified_at'],
    ]);
    break;

case 'undislike':
    // 补全过滤条件,仅删除当前用户对当前图片的点踩记录
    $this->builder()
        ->where([
            'action'   => 0,
            'username' => session()->get('username'),
            'viewkey'  => $request['viewkey']
        ])
        ->delete();
    break;

case 'like':
    $username = session()->get('username');
    $viewkey = $request['viewkey'];
    // 清除当前用户对该图片的所有历史赞/踩记录
    $this->builder()
        ->whereIn('action', [0, 1])
        ->where(['username' => $username, 'viewkey' => $viewkey])
        ->delete();
    // 写入新的点赞记录
    $this->builder()->insert([
        'action'      => 1,
        'username'    => $username,
        'viewkey'     => $viewkey,
        'modified_at' => $request['modified_at'],
    ]);
    break;

case 'unlike':
    // 补全过滤条件,仅删除当前用户对当前图片的点赞记录
    $this->builder()
        ->where([
            'action'   => 1,
            'username' => session()->get('username'),
            'viewkey'  => $request['viewkey']
        ])
        ->delete();
    break;
额外加固建议
  • 给action表添加联合唯一索引UNIQUE KEY user_vote_unique (username, viewkey, action),从数据库层面杜绝同用户同图片同操作类型的重复记录生成,即使代码逻辑出现疏漏也不会产生脏数据
  • 清理代码中所有无效的unset对象方法/属性语句,避免产生不必要的PHP警告
  • 浏览、收藏分支的更新、删除操作也需要补全username和viewkey过滤条件,避免出现误删全表数据的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 18:09:21