Мульти HTTP-запрос на CURL
Иногда возникает необходимость во время исполнения скрипта сделать несколько http запросов. При большом их количестве возникает проблема со временем обработки скрипта т.к. все запросы делаются по очереди и общее время их выполнения будет равно сумме времен потраченных на каждый запрос в отдельности. Хорошо если запросов 5, а если их 100? Сами представляете сколько будет выполняться скрипт. Но выход есть!
Мы будем использовать библиотеку CURL, у которой есть возможность создавать мульти запросы.
Что нам это дает? Общее время выполнения всех запросов будет равно времени выполнения самого долгого запроса. Согласитесь это очень круто!
Вот собственно функция которая все это сделает:
/**
* Функция мульти запроса на CURL
* @param array $data Данные для запроса
* @param array $options Опции для всех запросов
* @param array $oneoptions Опции для отдельных запросов
* @return array
*/
function multiRequest($data, $options = array(), $oneoptions = array()) {
// Массив для ресурсов соединения
$curls = array();
// Массив для результатов
$result = array();
// Инициализация мульти запроса
$mh = curl_multi_init();
// Задание параметров запроса
foreach ($data as $id => $d)
{
$curls[$id] = curl_init();
$url = (is_array($d) && !empty($d['url'])) ? $d['url'] : $d;
curl_setopt($curls[$id], CURLOPT_URL, $url);
curl_setopt($curls[$id], CURLOPT_HEADER, false);
curl_setopt($curls[$id], CURLOPT_RETURNTRANSFER, true);
// Дополнительные опции общие запросов
if (!empty($options))
{
curl_setopt_array($curls[$id], $options);
}
// Дополнительные опции для определенного запроса
if (!empty($oneoptions[$id]))
{
curl_setopt_array($curls[$id], $oneoptions[$id]);
}
// Если post запрос
if (is_array($d))
{
if (!empty($d['post']))
{
curl_setopt($curls[$id], CURLOPT_POST, 1);
curl_setopt($curls[$id], CURLOPT_POSTFIELDS, $d['post']);
}
}
curl_multi_add_handle($mh, $curls[$id]);
}
// Выполняем запрос пока есть соединения
$running = null;
do
{
curl_multi_exec($mh, $running);
}
while($running > 0);
// Получаем данные и закрываем соединения
foreach($curls as $id => $content)
{
$result[$id] = curl_multi_getcontent($content);
curl_multi_remove_handle($mh, $content);
}
curl_multi_close($mh);
return $result;
}
Примеры использования.
1) Простой GET запрос с дополнительными параметрами:
$data = array( 'http://webiteam.ru/test/multicurl/test.php?data=This+is+get+first', 'http://webiteam.ru/test/multicurl/test.php?data=This+is+get+second', 'http://webiteam.ru/test/multicurl/test.php?data=This+is+get+third', ); $options = array( CURLOPT_REFERER => 'http://webiteam.ru/', CURLOPT_TIMEOUT => 5 ); $oneoptions[0] = array(CURLOPT_USERAGENT => 'IE'); $r = multiRequest($data, $options,$oneoptions); var_dump($r);
Результат:
array 0 => string 'This is get first http://webiteam.ru/ IE ' (length=41) 1 => string 'This is get second http://webiteam.ru/ ' (length=39) 2 => string 'This is get third http://webiteam.ru/ ' (length=38)
2) POST запрос с дополнительными параметрами:
$data = array(array(),array()); $data[0]['url'] = 'http://webiteam.ru/test/multicurl/test.php'; $data[0]['post']['postdata'] = 'This is post first'; $data[1]['url'] = 'http://webiteam.ru/test/multicurl/test.php'; $data[1]['post']['postdata'] = 'This is post second'; $options = array( CURLOPT_TIMEOUT => 10 ); $oneoptions[0] = array(CURLOPT_USERAGENT => 'Mozilla'); $oneoptions[1] = array(CURLOPT_USERAGENT => 'Opera'); $r = multiRequest($data, $options, $oneoptions); var_dump($r);
Результат:
array 0 => string 'This is post first Mozilla ' (length=27) 1 => string 'This is post second Opera ' (length=26)
Как видите ничего сложного!
Список всех дополнительных опций для CURL тут.
Рекомендую также следующие статьи:
