在 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']);
遍历您的列表,将返回的句柄与每个存储的句柄进行比较,然后使用相应的键填写您的响应。
在我的场景中,我可能需要发出 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']);
遍历您的列表,将返回的句柄与每个存储的句柄进行比较,然后使用相应的键填写您的响应。