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

PHP买赠优惠脚本问题:免费商品数量计算错误排查

解决「买N赠M」优惠活动中免费商品数量计算错误的问题

问题背景

需开发PHP脚本支持管理员配置「购买N件指定商品,获赠M件指定商品」的优惠,计算总商品中的免费商品数量,覆盖以下优惠类型:

  • 买1赠1
  • 买1赠2
  • 买2赠1
  • 买4赠3

现有测试代码通过修改顶部$buy和$get变量调整规则,但遇到问题:当购物车总数量为2(如p1=1、p2=1)时,预期免费商品数为1,但实际计算结果为0。

现有代码

$buy = 1;
$get = 2;
$free= 0;
$sum = $buy + $get;

for($qty=1;$qty<=100;$qty++)
{
    if($buy >= $get){
        $free= (int) round(($qty/$sum), PHP_ROUND_HALF_DOWN);
    }else if($buy < $get){
        $free= (int) round(($qty/$sum), PHP_ROUND_HALF_UP);
    }
    
    $free*= $get;
     
    echo "Result = Qty = ".$qty." Free = ".($free)."\n";
   
}

问题分析

现有代码的核心错误是使用四舍五入计算优惠组数,不符合「买N赠M」的实际逻辑:

  1. 四舍五入规则无法匹配优惠的阶梯性要求,比如当$buy=2、$get=1时,总数量2除以sum=3得到0.666,用HALF_DOWN舍去为0,导致免费数为0,这符合买2赠1的规则(需凑够3件才能得1件免费),但如果是买1赠1的规则,这种逻辑就会出错。
  2. 代码未限制免费数量不能超过总商品数,比如当$buy=1、$get=2时,总数量2会算出免费数2,显然不合理(总数量才2,不可能全是免费)。

正确解决方案

正确逻辑是:根据「每购买$buy件付费商品,可获得$get件免费商品」的规则,计算最大免费数量,同时满足付费数量 = 总数量 - 免费数量,且付费数量需足够支撑对应的免费数量。

通过数学推导得出免费数量最大值:
$$free = \lfloor \frac{qty \times get}{buy + get} \rfloor$$

同时增加验证,避免极端情况导致付费数量不足。修正后的代码:

$buy = 1;
$get = 1;
$sum = $buy + $get;

for($qty=1;$qty<=100;$qty++)
{
    // 计算最大可能的免费数量
    $free = (int) floor(($qty * $get) / $sum);
    
    // 验证付费数量是否足够支撑免费数量
    $paid = $qty - $free;
    while ($paid < ceil($free / $get) * $buy && $free > 0) {
        $free--;
        $paid = $qty - $free;
    }
    
    echo "Result = Qty = ".$qty." Free = ".($free)."\n";
}

验证示例

  • 当规则为买1赠1($buy=1、$get=1),总数量2时:
    $$free = floor((2*1)/(1+1)) = 1$$
    符合预期结果。
  • 当规则为买2赠1($buy=2、$get=1),总数量3时:
    $$free = floor((3*1)/(2+1)) = 1$$
    符合优惠逻辑。
  • 当规则为买1赠2($buy=1、$get=2),总数量2时:
    $$free = floor((2*2)/(1+2)) = 1$$
    付费数量1满足买1件的要求,免费1件符合合理预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 11:01:01