在 php 中获得 multi-curl 响应时如何控制接收数据的顺序?

How do I control the order I receive data when getting a response of a multi-curl in php?

在我的场景中,我可能需要发出 100 多个 curl 请求来获取我需要的信息。没有办法事先获得这些信息,而且我无权访问我将向其发出请求的服务器。我的计划是使用curl_multi_init()。每个回复都将进入 json。问题是我需要按照我放置的顺序接收信息,否则我将不知道响应返回后一切都去了哪里。我该如何解决这个问题。

显然,由于请求是异步的,您无法预测响应到达的顺序。因此,在您的设计中,您必须为每个请求提供包括 "some random bit of information"——所谓的 nonce——每个客户端将以某种方式被迫 return你逐字逐句。

基于此 "nonce," 然后您将能够将每个响应与发起它的请求配对 – 并丢弃在 "out of the blue."

中漫游的任何随机垃圾位

否则,没有(!)解决您的问题。

当您从 curl_multi_info_read 取回句柄时,您可以将这些句柄与您的键控列表进行比较,然后当然可以使用键来了解您的响应去向。这是基于我用于抓取器的模型的直接实现:

// here's our list of URL, in the order we care about
$easy_handles['google']     = curl_init('https://google.com/');
$easy_handles['bing']       = curl_init('https://bing.com/');
$easy_handles['duckduckgo'] = curl_init('https://duckduckgo.com/');

// our responses will be here, keyed same as URL list
$responses = [];

// here's the code to do the multi-request -- it's all boilerplate
$common_options = [ CURLOPT_FOLLOWLOCATION => true, CURLOPT_RETURNTRANSFER => true ];
$multi_handle = curl_multi_init();
foreach ($easy_handles as $easy_handle) {
    curl_setopt_array($easy_handle, $common_options);
    curl_multi_add_handle($multi_handle, $easy_handle);
}
do {
    $status = curl_multi_exec($multi_handle, $runCnt);
    assert(CURLM_OK === $status);
    do {
        $status = curl_multi_select($multi_handle, 2/*seconds timeout*/);
        if (-1 === $status) usleep(10); // reported bug in PHP
    } while (0 === $status);
    while (false !== ($info = curl_multi_info_read($multi_handle))) {
        foreach ($easy_handles as $key => $easy_handle) { // find the response handle
            if ($info['handle'] === $easy_handle) {       // from our list
                if (CURLE_OK === $info['result']) {
                    $responses[$key] = curl_multi_getcontent($info['handle']);
                } else {
                    $responses[$key] = new \RuntimeException(
                        curl_strerror($info['result'])
                    );
                }
            }
        }
    }
} while (0 < $runCnt);

其中大部分是用于执行多重提取的样板机制。针对您的特定问题的行是:

foreach ($easy_handles as $key => $easy_handle) { // find the response handle
    if ($info['handle'] === $easy_handle) {       // from our list
        if (CURLE_OK === $info['result']) {
            $responses[$key] = curl_multi_getcontent($info['handle']);

遍历您的列表,将返回的句柄与每个存储的句柄进行比较,然后使用相应的键填写您的响应。