Использование curl_multi_exec в PHP

Привет всем! В статье рассматривается использование curl_multi_exec в PHP для реализации множественных запросов.

Скорее всего, вы использовали cURL в PHP для выполнения запросов один за одним. При этом общее время выполнения складывалось из времени выполнения всех запросов.

Допустим, ваше PHP приложение должно делать запросы к нескольким серверам, либо к одному серверу передавая разные данные. Таким образом, нам нужно делать cURL запрос к каждому из серверов, и это увеличивает общее время запроса.

Используя curl_multi_exec, мы можем выполнять все эти запросы параллельно, тем самым общее время запроса будет равно времени самого медленного из запросов.

Пример

Приведем пример, в котором нам нужно запрашивать записи с сервера по ID.

Используя curl мы должны для каждого ID в цикле делать запросы к серверу. Если у нас есть 10 ID, то получаем 10 последовательных запросов и 10ти-кратное увеличение общего времени запроса:

$result = [] ;
foreach ($ids as $id) {
  // URL from which data will be fetched
  $fetchURL = 'https://example.com&customerId='.$id;
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $fetchURL);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  $result[] = curl_exec($ch);
  curl_close($ch);
}

Но если мы будем использовать параллельные запросы cURL, то общее время запроса значительно уменьшается:


// array of curl handles
$multiCurl = [];
// data to be returned
$result = [];
// multi handle
$mh = curl_multi_init();
foreach ($ids as $i => $id) {
  // URL from which data will be fetched
  $fetchURL = 'https://example.com&customerId='.$id;
  $multiCurl[$i] = curl_init();
  curl_setopt($multiCurl[$i], CURLOPT_URL,$fetch_url);
  curl_setopt($multiCurl[$i], CURLOPT_HEADER,0);
  curl_setopt($multiCurl[$i], CURLOPT_RETURNTRANSFER,1);
  curl_multi_add_handle($mh, $multiCurl[$i]);
}
$index=null;
do {
  curl_multi_exec($mh,$index);
} while($index > 0);
// get content and remove handles
foreach($multiCurl as $k => $ch) {
  $result[$k] = curl_multi_getcontent($ch);
  curl_multi_remove_handle($mh, $ch);
}
// close
curl_multi_close($mh);

Результатом каждого из cURL запроса будет находиться в переменной $result, например вот так:

$result[0] => {"id1":{"customerName":"John","customerAddress":...
$result[1] => {"id2":{"customerName":"JDoe","customerAddress":...
....

79