PHP MySQL推荐佣金系统:如何跳过不活跃推荐人
推荐佣金脚本:跳过不活跃用户的问题分析与修复方案
首先,咱们来拆解你当前代码的核心问题,然后一步步解决:
问题出在哪?
你的代码现在有三个关键问题,导致会给不活跃用户发佣金,还没实现「跳过不活跃用户向上追溯」的需求:
- 完全没做活跃性校验:不管是查询推荐链的SQL,还是发放佣金的循环,都没有检查用户是否活跃——只要推荐人不是
_,就直接发钱。 - 固定层级逻辑不支持跳过:你用链式JOIN一次性拉了7层推荐人,但如果中间某层用户不活跃,你没有跳过他去往上找下一个活跃用户,而是依然按原层级发佣金,完全不符合需求。
- 额外风险:SQL注入:你直接把
$userid这类变量拼进SQL语句里,很容易被恶意攻击,这个得顺便修复。
怎么解决?
我们需要重构推荐链的获取逻辑,改成循环向上查找活跃用户,直到凑够6个活跃推荐人或者没有更高层级为止。下面是具体的修复代码,我会一步步解释:
第一步:先明确活跃用户的判断字段
假设你的users表里有个is_active字段(1代表活跃,0代表不活跃),如果你的字段名不一样,记得替换成你实际的判断字段(比如最近登录时间、是否完成认证等)。
第二步:重构推荐链获取与佣金发放逻辑
替换你原来的查询和循环代码,改成下面的逻辑:
// 初始化变量:从当前用户开始向上找 $currentSponsor = $userid; $activeReferrers = []; $maxCommissionLevels = 6; // 最高6级佣金 // 循环向上找活跃推荐人,直到凑够6个或者没有更高层级 while (count($activeReferrers) < $maxCommissionLevels) { // 查询当前用户的推荐人信息(用预处理语句防注入) $stmt = mysqli_prepare($conn, "SELECT sponsorid FROM users WHERE username = ?"); mysqli_stmt_bind_param($stmt, "s", $currentSponsor); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $userData = mysqli_fetch_array($result); // 如果没有推荐人了,直接终止循环 if (!$userData || $userData['sponsorid'] == '_') { break; } $sponsorId = $userData['sponsorid']; // 检查这个推荐人是否活跃 $stmtActive = mysqli_prepare($conn, "SELECT is_active FROM users WHERE username = ?"); mysqli_stmt_bind_param($stmtActive, "s", $sponsorId); mysqli_stmt_execute($stmtActive); $activeResult = mysqli_stmt_get_result($stmtActive); $sponsorIsActive = mysqli_fetch_array($activeResult); // 如果活跃,就加入到待发佣金的列表里 if ($sponsorIsActive && $sponsorIsActive['is_active'] == 1) { $activeReferrers[] = $sponsorId; } // 不管当前推荐人活跃与否,都继续向上找下一个推荐人 $currentSponsor = $sponsorId; } // 准备各层级的佣金比例(对应1-6级) $commissionRates = [ 1 => $refpc1, 2 => $refpc2, 3 => $refpc3, 4 => $refpc4, 5 => $refpc5, 6 => $refpc6 ]; // 给每个活跃推荐人发放对应层级的佣金 $today = date("Y-m-d"); foreach ($activeReferrers as $level => $referrer) { $commissionAmount = ($invest_to_add / 100) * $commissionRates[$level]; // 更新用户的收益(同样用预处理语句) $stmtUpdate = mysqli_prepare($conn, "UPDATE users SET earned = earned + ? WHERE username = ?"); mysqli_stmt_bind_param($stmtUpdate, "ds", $commissionAmount, $referrer); mysqli_stmt_execute($stmtUpdate); // 添加佣金记录到credits表 $stmtInsert = mysqli_prepare($conn, "INSERT INTO credits(s_date, s_reason, s_amount, s_user, s_type) VALUES(?, ?, ?, ?, ?)"); $reason = "Ref. comission from $userid"; mysqli_stmt_bind_param($stmtInsert, "ssdis", $today, $reason, $commissionAmount, $referrer, 1); mysqli_stmt_execute($stmtInsert) or die(mysqli_error($conn)); }
第三步:代码逻辑说明
- 我们从当前用户
$userid开始,一层层向上找他的推荐人 - 每找到一个推荐人,先检查他是否活跃,活跃才加入佣金列表
- 不管当前推荐人活跃与否,都继续往上找,这样就能跳过不活跃用户,直接追溯到上面的活跃用户
- 用了mysqli预处理语句,彻底解决SQL注入的风险
- 最多找6个活跃推荐人,符合你最高6级佣金的需求
额外注意事项
- 如果你没有
is_active字段,需要先给users表添加这个字段,或者替换成你实际判断用户活跃的逻辑(比如last_login > DATE_SUB(NOW(), INTERVAL 30 DAY)) - 测试的时候,可以手动设置几个不活跃的用户,看看佣金是否会跳过他们,直接发给上面的活跃用户
内容的提问来源于stack exchange,提问作者kamrul
相关产品推荐
相关产品推荐

