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

long polling实现Telegram板球比分机器人触发Maximum execution time exceed报错如何解决

问题原因分析

首先梳理你现有代码的核心问题:

  • 执行环境问题:如果是通过web服务器(Nginx/Apache)运行该PHP脚本,PHP默认配置的max_execution_time(通常为30秒)会限制脚本运行时长,死循环运行几十秒就会触发Maximum execution time exceed报错。
  • 逻辑错误:你先将$_SESSION["score"]赋值为当前比分,再判断二者是否不等,这个条件永远为假,根本不会触发消息发送。
  • 存储介质错误:session是面向web端单用户请求的临时存储,不仅CLI模式下无法使用,而且单次脚本结束后session就会失效,根本无法存储上一次请求的比分数据。
  • 缺少异常处理:file_get_contents请求第三方API没有超时、错误捕获逻辑,一旦API超时或响应异常,会直接导致脚本崩溃。
最优实现方案

有两种成熟方案可选,可根据你的运维习惯选择:

方案1:CLI常驻进程方案(适合低延迟推送)

改用PHP CLI模式运行脚本,CLI模式默认关闭最大执行时间限制,不会触发超时错误,搭配缓存存储历史比分即可实现需求。

修正后代码示例

<?php
$token = 'xyz';
$group_name = 'xyz';
// 用本地文件存储上一次的比分,也可以替换为Redis等缓存
$scoreCacheFile = __DIR__ . '/last_score.txt';

while(true){
    // 给HTTP请求加5秒超时配置,避免被卡住
    $context = stream_context_create([
        'http' => [
            'timeout' => 5
        ]
    ]);
    
    try {
        $ipl = @file_get_contents('https://cricket-api.vercel.app/cri.php?url=https://www.cricbuzz.com/live-cricket-scores/38708/rocks-vs-war-pool-d-csa-provincial-t20-cup-2021', false, $context);
        if (!$ipl) throw new Exception('赛事API请求失败');
        
        $ipl_data = json_decode($ipl, true);
        if (!isset($ipl_data['livescore']['current'])) throw new Exception('比分解析失败');
        
        $current_score = $ipl_data['livescore']['current'];
        // 读取上一次存储的比分
        $last_score = file_exists($scoreCacheFile) ? file_get_contents($scoreCacheFile) : '';
        
        // 比分不一致才发送消息
        if ($current_score != $last_score) {
            // 对内容做urlencode,避免特殊字符导致Telegram接口请求失败
            $sendUrl = "https://api.telegram.org/bot{$token}/sendMessage?chat_id={$group_name}&text=" . urlencode($current_score);
            @file_get_contents($sendUrl, false, $context);
            // 更新存储的最新比分
            file_put_contents($scoreCacheFile, $current_score);
        }
    } catch (Exception $e) {
        // 可自行添加错误日志记录逻辑
    }
    
    sleep(10);
}
?>

运行方式

在服务器终端执行php 你的脚本文件名.php即可,需要后台运行的话可以用nohup或者systemd托管进程,避免终端关闭后脚本停止。

方案2:定时任务方案(稳定性更高)

如果不想维护常驻进程,可以用Linux系统的crontab定时任务执行脚本,去掉死循环,每次脚本执行完就退出,完全不会有超时问题:

  1. 把上述代码中的while(true)和sleep(10)逻辑删除
  2. 配置crontab,每分钟执行6次脚本(间隔10秒),配置示例:
* * * * * php /path/to/your/script.php
* * * * * sleep 10; php /path/to/your/script.php
* * * * * sleep 20; php /path/to/your/script.php
* * * * * sleep 30; php /path/to/your/script.php
* * * * * sleep 40; php /path/to/your/script.php
* * * * * sleep 50; php /path/to/your/script.php

这种方案的优势是脚本不需要一直挂着,就算某次执行崩溃了下次还会自动执行,运维成本更低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 01:57:03