我可以使用Guzzle執行單個請求,我對Guzzle的表現非常滿意,但是我在Guzzle API中閱讀了一些關於MultiCurl和Batching的內容。如何同時執行多個Guzzle請求?
有人可以向我解釋如何同時發出多個請求嗎?異步如果可能的話。我不知道這是否與MultiCurl意味着什麼。同步也不是問題。我只想同時或非常接近地完成多個請求(很短的時間)。
我可以使用Guzzle執行單個請求,我對Guzzle的表現非常滿意,但是我在Guzzle API中閱讀了一些關於MultiCurl和Batching的內容。如何同時執行多個Guzzle請求?
有人可以向我解釋如何同時發出多個請求嗎?異步如果可能的話。我不知道這是否與MultiCurl意味着什麼。同步也不是問題。我只想同時或非常接近地完成多個請求(很短的時間)。
從文檔: http://guzzle3.readthedocs.org/http-client/client.html#sending-requests-in-parallel
對於一個易於使用的溶液返回的請求的哈希對象映射到的響應或錯誤,請參閱http://guzzle3.readthedocs.org/batching/batching.html#batching
短例如:
<?php
$client->send(array(
$client->get('http://www.example.com/foo'),
$client->get('http://www.example.com/baz'),
$client->get('http://www.example.com/bar')
));
有關新的GuzzleHttp的更新guzzlehttp/guzzle
併發/並行調用現在通過一些不同的方法執行,包括Promises .. Concurrent Requests
傳遞RequestInterfaces數組的舊方法不再有效。
見例如這裏
$newClient = new \GuzzleHttp\Client(['base_uri' => $base]);
foreach($documents->documents as $doc){
$params = [
'language' =>'eng',
'text' => $doc->summary,
'apikey' => $key
];
$requestArr[$doc->reference] = $newClient->getAsync('/1/api/sync/analyze/v1?' . http_build_query($params));
}
$time_start = microtime(true);
$responses = \GuzzleHttp\Promise\unwrap($requestArr); //$newClient->send($requestArr);
$time_end = microtime(true);
$this->get('logger')->error(' NewsPerf Dev: took ' . ($time_end - $time_start));
更新: 作爲意見建議,並通過@ sankalp-tambe問,你也可以使用不同的方法,以避免一組與併發請求的失敗將不會返回所有的迴應。
雖然Pool提出的選項是可行的,但我更喜歡承諾。
承諾的一個例子是使用結算和等待方法,而不是解包。
從例子中的差異上面會
$responses = \GuzzleHttp\Promise\settle($requestArr)->wait();
我已經創建了下面有關如何處理$迴應過參考一個完整的例子。
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Promise as GuzzlePromise;
$client = new GuzzleClient(['timeout' => 12.0]); // see how i set a timeout
$requestPromises = [];
$sitesArray = SiteEntity->getAll(); // returns an array with objects that contain a domain
foreach ($sitesArray as $site) {
$requestPromises[$site->getDomain()] = $client->getAsync('http://' . $site->getDomain());
}
$results = GuzzlePromise\settle($requestPromises)->wait();
foreach ($results as $domain => $result) {
$site = $sitesArray[$domain];
$this->logger->info('Crawler FetchHomePages: domain check ' . $domain);
if ($result['state'] === 'fulfilled') {
$response = $result['value'];
if ($response->getStatusCode() == 200) {
$site->setHtml($response->getBody());
} else {
$site->setHtml($response->getStatusCode());
}
} else if ($result['state'] === 'rejected') {
// notice that if call fails guzzle returns is as state rejected with a reason.
$site->setHtml('ERR: ' . $result['reason']);
} else {
$site->setHtml('ERR: unknown exception ');
$this->logger->err('Crawler FetchHomePages: unknown fetch fail domain: ' . $domain);
}
$this->entityManager->persist($site); // this is a call to Doctrines entity manager
}
此示例代碼最初發布爲here。
在文檔中有一個[此示例](http://guzzlephp.org/http-client/client.html#sending-requests-in-parallel)。從您的角度來看,這仍然是一個同步調用,但內部並行 - 因此調用的總時間只是單次最長提取的時間。 – halfer