Асинхронный curl запрос с помощью GuzzleHttp

Бывает нужно выполнять параллельные запросы к сайтам, это можно сделать с помощью библиотеки GuzzleHttp.

Бывает нужно выполнять параллельные запросы к сайтам, это можно сделать с помощью библиотеки GuzzleHttp.


Установка

composer require guzzlehttp/guzzle:^7.0


Ниже привожу код скрипта, который выполняет параллельные запросы к домену по разным адресам. Каждая страница отвечает за разное время, это показывает последовательность ответов.


<?php
require 'vendor/autoload.php';

$client = new \GuzzleHttp\Client([
  'base_uri' => 'http://localhost',
]);

// Список адресов
$urls = [
  '/page.php?1',
  '/page.php?2',
  '/page.php?3',
  '/page.php?4',
  '/page.php?5',
];

$promises = [];

foreach($urls as $urlIndex => $url) {
  $request = new \GuzzleHttp\Psr7\Request('GET', $url, []);

  echo date('d.m.Y H:i:s') . ' запрос ' . $url . PHP_EOL;

  $promises[$urlIndex] = $client->sendAsync($request, [
    'timeout' => 10,
    'on_stats' => function (\GuzzleHttp\TransferStats $stats) use ($url) {
      // Тут можно получить статистику запроса
      $stat = $stats->getHandlerStats();
      echo date('d.m.Y H:i:s') . ' получена статистика ' . $url . PHP_EOL;
    }
  ]);

  $promises[$urlIndex]->then(
    function (\Psr\Http\Message\ResponseInterface $res) use ($url) {
      // Тут обработка ответа
      echo date('d.m.Y H:i:s') . ' запрос выполнен ' . $url . PHP_EOL;
    },
    function (\GuzzleHttp\Exception\RequestException $e) {
      // Тут обработка ошибки
    }
  );
}

// Ждать ответов
$results = \GuzzleHttp\Promise\Utils::settle($promises)->wait(true);

// Обработка результатов по всем запросам
if(sizeof($results) > 0) {
  foreach ($results as $urlIndex => $result) {
    // Обработка ответа по запросу $urls[$urlIndex]

    if ($result['state'] != 'fulfilled' || !isset($result['value'])) {
      // Если запрос выполнился с ошибкой
      continue;
    }

    /** @var \GuzzleHttp\Psr7\Response $response */
    $response = $result['value'];

    // Получение заголовков
    // $response->getHeaderLine('Content-Length');

    // Обработка тела ответа
    $body = $response->getBody();
    echo date('d.m.Y H:i:s') . ' обработка запроса в цикле' . $urls[$urlIndex] . PHP_EOL;
  }
}


Результат работы скрипта

Видно, что страница page.php отвечает за разное время, поэтому результаты приходят не последовательно.


14.08.2021 18:08:50 запрос /page.php?1
14.08.2021 18:08:50 запрос /page.php?2
14.08.2021 18:08:50 запрос /page.php?3
14.08.2021 18:08:50 запрос /page.php?4
14.08.2021 18:08:50 запрос /page.php?5

14.08.2021 18:08:52 получена статистика /page.php?5
14.08.2021 18:08:52 запрос выполнен /page.php?5
14.08.2021 18:08:54 получена статистика /page.php?1
14.08.2021 18:08:54 получена статистика /page.php?2
14.08.2021 18:08:54 получена статистика /page.php?4
14.08.2021 18:08:54 запрос выполнен /page.php?1
14.08.2021 18:08:54 запрос выполнен /page.php?2
14.08.2021 18:08:54 запрос выполнен /page.php?4
14.08.2021 18:08:56 получена статистика /page.php?3
14.08.2021 18:08:56 запрос выполнен /page.php?3

14.08.2021 18:08:56 обработка запроса в цикле/page.php?1
14.08.2021 18:08:56 обработка запроса в цикле/page.php?2
14.08.2021 18:08:56 обработка запроса в цикле/page.php?3
14.08.2021 18:08:56 обработка запроса в цикле/page.php?4
14.08.2021 18:08:56 обработка запроса в цикле/page.php?5


Оставить комментарий

Комментарий отправится на проверку

Отправка
Спасибо! Комментарий добавлен
Копировать можно с указанием активной ссылки на эту страницу.
Давайте уважать труд других.