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

PHP导入Unibet XML赔率至数据库仅插入2条:dec2frac函数异常排查

问题排查与修复方案

嘿,从你描述的情况来看,核心问题百分百出在dec2frac函数上——它要么在处理部分十进制赔率时抛出了未捕获的错误,要么返回了数据库不接受的无效值,导致插入流程直接卡壳,只完成了2条记录的插入。移除它后所有投注项都能正常插入,说明函数本身的逻辑或者错误处理有漏洞,咱们一步步来解决:

先定位函数的问题点

首先得搞清楚是哪些赔率值触发了异常,给dec2frac加上错误捕获和日志记录,就能精准定位掉链子的地方:

function dec2frac($decimal) {
    try {
        // 保留你原有的函数逻辑
        if ($decimal == 0) return "0/1";
        $numerator = 1;
        $denominator = 1;
        $epsilon = 1e-6;
        $sign = $decimal < 0 ? -1 : 1;
        $decimal = abs($decimal);
        
        while (abs($decimal - $numerator/$denominator) > $epsilon) {
            if ($decimal > $numerator/$denominator) {
                $numerator++;
            } else {
                $denominator++;
            }
        }
        return $sign * $numerator . "/" . $denominator;
    } catch (Exception $e) {
        // 把错误信息和出问题的赔率值写入日志
        error_log("dec2frac处理失败!值为:{$decimal},错误:{$e->getMessage()}");
        // 返回数据库能接受的默认值,避免插入流程中断
        return "0/1";
    }
}

另外,你的插入代码可能没处理数据库报错——如果某条记录插入失败,脚本可能直接终止。给插入逻辑也加上错误捕获,保证一条失败不影响其他:

// 假设你用PDO操作数据库
try {
    $stmt = $pdo->prepare("INSERT INTO your_table (event_id, odds) VALUES (?, ?)");
    $stmt->execute([$eventId, $calculatedOdds]);
} catch (PDOException $e) {
    error_log("赛事{$eventId}插入失败!赔率值:{$calculatedOdds},错误:{$e->getMessage()}");
    // 跳过这条记录,继续处理下一个赛事
    continue;
}

优化函数逻辑,避免死循环或无效返回

你原来的dec2frac用循环逼近分数,某些特殊十进制值可能会让循环无限运行(比如无法用简单分数精准表示的数值),导致脚本超时,只完成部分插入。给循环加个最大次数限制:

function dec2frac($decimal) {
    if ($decimal == 0) return "0/1";
    $numerator = 1;
    $denominator = 1;
    $epsilon = 1e-6;
    $sign = $decimal < 0 ? -1 : 1;
    $decimal = abs($decimal);
    $maxLoops = 1000; // 防止无限循环
    $loopCount = 0;
    
    while (abs($decimal - $numerator/$denominator) > $epsilon && $loopCount < $maxLoops) {
        if ($decimal > $numerator/$denominator) {
            $numerator++;
        } else {
            $denominator++;
        }
        $loopCount++;
    }
    // 如果达到最大循环次数,返回原十进制的字符串形式兜底
    if ($loopCount >= $maxLoops) {
        error_log("dec2frac处理超时!值为:{$decimal}");
        return (string)$decimal;
    }
    return $sign * $numerator . "/" . $denominator;
}

插入前验证格式合法性

最后,在插入数据库前,先检查dec2frac的返回值是否符合数据库字段要求(比如是不是数字/数字的标准分数格式):

$calculatedOdds = dec2frac($decimalOdds);
// 用正则验证分数格式
if (!preg_match('/^-?\d+\/\d+$/', $calculatedOdds)) {
    error_log("无效的赔率格式!原十进制值:{$decimalOdds},转换后:{$calculatedOdds}");
    // 换成数据库能接受的格式,比如直接用原十进制值
    $calculatedOdds = (string)$decimalOdds;
}
// 再执行插入操作

按照上面的步骤来,你既能保留赔率转换的功能,又能保证所有赛事的投注记录都能正常插入数据库啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:22:44