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

PHP实现按owner_id递增pos列至60后重置为1的问题修正

问题:player_gift表pos字段更新异常,同一owner_id的pos值全部相同

需求说明

需要更新player.player_gift表的pos字段,规则为:每个owner_id对应的pos从1开始依次递增,当pos超过60时重置为1。但现有代码执行后,同一owner_id下的所有pos值完全相同,不符合预期。

问题代码

$st = $dbh->query("SELECT * from player.player_gift");
$test = $st->fetchAll();

if(isset($_POST['pregatit'])) {

    foreach($test as $test2) {

        if(!is_null($test2['owner_id'])) {
            $st = $dbh->prepare('UPDATE player.player_gift SET pos = ? WHERE owner_id = ?');
            $st->execute([getRandomPositionFor($test2['owner_id']), $test2['owner_id']]);
        } else {
            // wh_log('id ul' . $test2['owner_id'] . 'a dat eroare');
        }
    }

    die();
}

function getRandomPositionFor($ownerid) {
    static $lastposinserted = 0;
    static $lastownerid = -1;
    $lastownerid = $ownerid;

    if($lastownerid != $ownerid) 
        $lastposinserted = 0;

    if($lastposinserted > 60)
        $lastposinserted = 0;

    $lastposinserted++;

    return $lastposinserted;
}

当前执行结果

owner_idpos
20441219
20441219
20441219
20440524
20440524
20440524
20440524
20439048
20439048
20439048

期望结果

owner_idpos
2044121
2044122
2044123
2044051
2044052
2044053
2044054
2043901
2043902
2043903

问题分析

  1. 函数逻辑错误:getRandomPositionFor函数中,先将$lastownerid赋值为当前$ownerid,再判断$lastownerid != $ownerid,这个判断永远不成立,导致切换owner_id时无法重置计数器。
  2. UPDATE条件错误:仅用owner_id作为WHERE条件,每次循环执行UPDATE都会覆盖该owner_id下的所有记录,最终所有记录都是最后一次调用函数返回的数值。
  3. 计数器未按owner_id隔离:全局静态变量$lastposinserted无法为每个owner_id独立维护递增计数,导致不同owner_id的计数混在一起。

修复后的代码

if(isset($_POST['pregatit'])) {
    // 按owner_id分组查询,确保同一owner_id的记录连续处理
    $st = $dbh->query("SELECT * from player.player_gift ORDER BY owner_id");
    $test = $st->fetchAll();

    // 用数组维护每个owner_id的当前pos计数
    $ownerPosCounts = [];

    foreach($test as $test2) {
        $ownerId = $test2['owner_id'];
        if(is_null($ownerId)) {
            // wh_log('id ul' . $ownerId . 'a dat eroare');
            continue;
        }

        // 初始化当前owner_id的计数
        if(!isset($ownerPosCounts[$ownerId])) {
            $ownerPosCounts[$ownerId] = 0;
        }

        // 递增计数,超过60重置为1
        $ownerPosCounts[$ownerId]++;
        if($ownerPosCounts[$ownerId] > 60) {
            $ownerPosCounts[$ownerId] = 1;
        }

        // 使用唯一主键(假设表中有id字段)更新单条记录,避免批量覆盖
        $st = $dbh->prepare('UPDATE player.player_gift SET pos = ? WHERE id = ?');
        $st->execute([$ownerPosCounts[$ownerId], $test2['id']]);
    }

    die();
}

修复说明

  • 按owner_id排序查询,保证同一owner_id的记录连续处理。
  • 用数组$ownerPosCounts为每个owner_id独立维护pos计数器,避免全局变量的混乱。
  • UPDATE语句使用记录的唯一主键(如id)作为WHERE条件,确保每次只更新单条记录,实现逐个递增。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:35:25