Send multiple requests simultaneously
Parameters
$requests
arrayrequired- Request data
$options
arrayrequired- Global options
Source
// If you're not requesting, we can't get any responses ¯\_(ツ)_/¯
if (empty($requests)) {
return [];
}
if (InputValidator::has_array_access($requests) === false || InputValidator::is_iterable($requests) === false) {
throw InvalidArgument::create(1, '$requests', 'array|ArrayAccess&Traversable', gettype($requests));
}
if (is_array($options) === false) {
throw InvalidArgument::create(2, '$options', 'array', gettype($options));
}
$multihandle = curl_multi_init();
$subrequests = [];
$subhandles = [];
$class = get_class($this);
foreach ($requests as $id => $request) {
$subrequests[$id] = new $class();
$subhandles[$id] = $subrequests[$id]->get_subrequest_handle($request['url'], $request['headers'], $request['data'], $request['options']);
$request['options']['hooks']->dispatch('curl.before_multi_add', [&$subhandles[$id]]);
curl_multi_add_handle($multihandle, $subhandles[$id]);
}
$completed = 0;
$responses = [];
$subrequestcount = count($subrequests);
$request['options']['hooks']->dispatch('curl.before_multi_exec', [&$multihandle]);
do {
$active = 0;
do {
$status = curl_multi_exec($multihandle, $active);
} while ($status === CURLM_CALL_MULTI_PERFORM);
$to_process = [];
// Read the information as needed
while ($done = curl_multi_info_read($multihandle)) {
$key = array_search($done['handle'], $subhandles, true);
if (!isset($to_process[$key])) {
$to_process[$key] = $done;
}
}
// Parse the finished requests before we start getting the new ones
foreach ($to_process as $key => $done) {
$options = $requests[$key]['options'];
if ($done['result'] !== CURLE_OK) {
//get error string for handle.
$reason = curl_error($done['handle']);
$exception = new CurlException(
$reason,
CurlException::EASY,
$done['handle'],
$done['result']
);
$responses[$key] = $exception;
$options['hooks']->dispatch('transport.internal.parse_error', [&$responses[$key], $requests[$key]]);
} else {
$responses[$key] = $subrequests[$key]->process_response($subrequests[$key]->response_data, $options);
$options['hooks']->dispatch('transport.internal.parse_response', [&$responses[$key], $requests[$key]]);
}
curl_multi_remove_handle($multihandle, $done['handle']);
curl_close($done['handle']);
if (!is_string($responses[$key])) {
$options['hooks']->dispatch('multiple.request.complete', [&$responses[$key], $key]);
}
$completed++;
}
} while ($active || $completed < $subrequestcount);
$request['options']['hooks']->dispatch('curl.after_multi_exec', [&$multihandle]);
curl_multi_close($multihandle);
return $responses;
}
User Contributed Notes
You must log in before being able to contribute a note or feedback.