如何在PHP中处理多个请求?

如何在PHP中处理多个请求?,php,telegram-bot,Php,Telegram Bot,我正在使用以下代码在php中创建一个简单的电报机器人: $message = json_decode(file_get_contents('php://input'), true); // if it's not a valid JSON return if(is_null($message)) return; $endpoint = "https://api.telegram.org/bot<token>/"; // make sure if text and chat_id i

我正在使用以下代码在php中创建一个简单的电报机器人:

$message = json_decode(file_get_contents('php://input'), true);
// if it's not a valid JSON return
if(is_null($message)) return;
$endpoint = "https://api.telegram.org/bot<token>/";

// make sure if text and chat_id is set into the payload
if(!isset($message["message"]["text"]) || !isset($message["message"]["chat"]["id"])) return;

// remove special characters, needed for the interpreter apparently
$text = $message["message"]["text"];
//$text = str_replace(["\r", "\n", "\t"], ' ', $text);
// saving chat_id for convenience
$chat_id = $message["message"]["chat"]["id"];

// show to the client that the bot is typing 
file_get_contents($endpoint."sendChatAction?chat_id=".$chat_id."&action=typing");
file_get_contents($endpoint."sendMessage?chat_id=".$chat_id."&text=hi");
$message=json\u解码(文件获取内容('php://input",对),;
//如果它不是有效的JSON返回
if(is_null($message))返回;
$endpoint=”https://api.telegram.org/bot/";
//确保文本和聊天室id已设置到有效负载中
如果(!isset($message[“message”][“text”])| |!isset($message[“message”][“chat”][“id”])返回;
//删除解释器所需的特殊字符
$text=$message[“message”][“text”];
//$text=str_replace([“\r”、“\n”、“\t”]、”$text);
//为方便起见,请保存聊天室id
$chat_id=$message[“message”][“chat”][“id”];
//向客户端显示bot正在键入
文件获取内容($endpoint.“sendChatAction?chat_id=”.$chat_id.&action=typing”);
文件获取内容($endpoint.“sendMessage?chat_id=”.$chat_id.&text=hi”);
但问题是同时响应多个请求。用户没有收到实时响应(延迟)。 我确信最后一行会导致延迟,并等待电报服务器的响应。 我怎么知道呢

更新 我找到了此代码,但仍有延迟:

$ch = curl_init();
    $curlConfig = array(
        CURLOPT_URL => 'https://api.telegram.org/bot<token>/sendMessage',
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true); 
    $curlConfig[CURLOPT_POSTFIELDS] = "chat_id=".$chat_id."&text='hi'";
    curl_setopt_array($ch, $curlConfig);
    $result = curl_exec($ch);
    curl_close($ch);
$ch=curl_init();
$curlConfig=array(
CURLOPT_URL=>'https://api.telegram.org/bot/sendMessage',
CURLOPT_POST=>true,
CURLOPT_RETURNTRANSFER=>true);
$curlConfig[CURLOPT_POSTFIELDS]=“chat_id=”.$chat_id.&text='hi';
curl_setopt_数组($ch,$curlConfig);
$result=curl\u exec($ch);
卷曲关闭($ch);

问题出在哪里?

如注释中所述,您可以使用简单的print语句在每个命令后输出(记录)时间戳。通过查看差异,您可以看到每个命令花费了多长时间。这应该足以确定一个简单函数中耗时的步骤

另一种方法是使用探查器。XDebug有一个内置的。但你必须设置,我怀疑这是合理的,只是为了找出哪一步需要这么长时间

然而,在我看来,最优雅的想法是在php中使用一个鲜为人知的特性:;-)


这允许注册一次“勾号”功能,并在执行每个命令时自动输出一个勾号。这样可以避免代码混乱。文档提供了一个很好的例子

电报机器人有两种不同的工作方式:

  • 直接https请求(您必须设置ssl证书)
  • 长轮询请求(脚本继续搜索更新)
在前一种情况下,您设置了一个webhook,在后一种情况下,您不需要它,只需使用getUpdatesAPI方法轮询即可。 好的,您得到的是输入流,所以我猜您使用的是推荐的第一种方法,它比轮询更快,因为您接收实时请求,并且能够动态地管理它。 Telegram向您发送带有一个或多个元素的JSON,您必须在同一请求期间处理这些元素,以避免多个连续消息之间的延迟:

// receives the request from telegram server
$message = json_decode(file_get_contents('php://input'), true);

// if it's not a valid JSON return
if(is_null($message)) return;

// check if data received doesn't contain telegram-side errors
if (!$message["ok"]) { return; }

// define remote endpoint
$endpoint = "https://api.telegram.org/bot<token>/";

// process each message contained in JSON request 
foreach ($message["result"] as $request) {

    // make sure if text and chat_id is set into the payload
    if(!isset($request["message"]["text"]) || !isset($request["message"]["chat"]["id"])) return;

    // remove special characters, needed for the interpreter apparently
    $text = $request["message"]["text"];
    //$text = str_replace(["\r", "\n", "\t"], ' ', $text);
    // saving chat_id for convenience
    $chat_id = $request["message"]["chat"]["id"];

    // show to the client that the bot is typing 
    file_get_contents($endpoint."sendChatAction?chat_id=".$chat_id."&action=typing");
    file_get_contents($endpoint."sendMessage?chat_id=".$chat_id."&text=hi");

}
//从电报服务器接收请求
$message=json\u解码(文件\u获取\u内容('php://input",对),;
//如果它不是有效的JSON返回
if(is_null($message))返回;
//检查接收的数据是否不包含电报端错误
如果(!$message[“ok”]){return;}
//定义远程端点
$endpoint=”https://api.telegram.org/bot/";
//处理JSON请求中包含的每条消息
foreach($message[“result”]作为$request){
//确保文本和聊天室id已设置到有效负载中
如果(!isset($request[“message”][“text”])| |!isset($request[“message”][“chat”][“id”])返回;
//删除解释器所需的特殊字符
$text=$request[“message”][“text”];
//$text=str_replace([“\r”、“\n”、“\t”]、”$text);
//为方便起见,请保存聊天室id
$chat_id=$request[“message”][“chat”][“id”];
//向客户端显示bot正在键入
文件获取内容($endpoint.“sendChatAction?chat_id=”.$chat_id.&action=typing”);
文件获取内容($endpoint.“sendMessage?chat_id=”.$chat_id.&text=hi”);
}

让我知道这是否会减少延迟,快乐的开发者!:)

通过对每一步进行计时。您只需在每个命令后记录一个时间戳即可。@arkascha谢谢。请您进一步解释一下,或者在php手册中给我一个链接好吗?:)
file\u get\u contents()
是一个阻塞调用。您正在编写同步代码。知道这对你来说可能是一个有帮助的开始:-)@jimbo谢谢你。实际上这不是我自己的代码。我在网上找到的;)感谢您提供详细信息;)我会测试它并通知你。我不知道为什么,但它失败了。好的,我看到你的代码应该运行良好,那天电报很慢。。。问题现在解决了吗?是的。我使用的是curl,它比file_get;)快得多多谢各位