07.07.2020 16:22

Получение ответов по нескольким URL-адресам в PHP с использованием многопоточности cURL

Получение ответов по нескольким URL-адресам в PHP с использованием многопоточности cURL

В этой статье я приведу пример того, как получить ответы по нескольким URL-адресам в PHP с использованием многопоточности cURL. Вы можете выполнять несколько запросов одновременно в асинхронном режиме с разделением на потоки. В обычном режиме выполнение нескольких запросов занимает много времени, потому что они выполняются последовательно один за другим. Но вы можете ускорить этот процесс, используя асинхронное выполнение запросов. Вы также можете избежать 100% загрузки процессора при использовании многопоточности. Используйте эту функцию для получения ответов по нескольким URL-адресам:

function getResponseByUrlsMultiThreads($urls, $threads = 10, $followLocation = false, $maxRedirects = 10)
{
    // Options
    $curlOptions = [
        CURLOPT_HEADER => false,
        CURLOPT_NOBODY => false,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 10,
        CURLOPT_CONNECTTIMEOUT => 10,
    ];

    if ($followLocation) {
        $curlOptions[CURLOPT_FOLLOWLOCATION] = true;
        $curlOptions[CURLOPT_MAXREDIRS] = $maxRedirects;
    }

    // Init multi-curl
    $mh = curl_multi_init();
    $chArray = [];

    $executeMethod = function ($mh, $chArray, &$result, &$running, &$currentThread) {
        usleep(100);
        while (curl_multi_exec($mh, $running) === CURLM_CALL_MULTI_PERFORM);
        curl_multi_select($mh);
        while ($done = curl_multi_info_read($mh)) {
            foreach ($chArray as $key => $ch) {
                if ($ch == $done['handle']) {
                    // Get response
                    $result[$key] = curl_multi_getcontent($ch);
                }
            }
            curl_multi_remove_handle($mh, $done['handle']);
            curl_close($done['handle']);
            $currentThread--;
        }
    };

    $result = [];
    $running = [];
    $currentThread = 0;

    $urls = !is_array($urls) ? [$urls] : $urls;
    foreach ($urls as $key => $url) {
        // Init of requests without executing
        $ch = curl_init($url);
        curl_setopt_array($ch, $curlOptions);

        $chArray[$key] = $ch;

        // Add the handle to multi-curl
        curl_multi_add_handle($mh, $ch);

        $currentThread++;
        if ($currentThread >= $threads) {
            while ($currentThread >= $threads) {
                $executeMethod($mh, $chArray, $result, $running, $currentThread);
            }
        }
    }

    do {
        $executeMethod($mh, $chArray, $result, $running, $currentThread);
    } while($running > 0);
    curl_multi_close($mh);

    return $result;
}

После вызова этой функции вы получите массив с ответами:

print_r(getResponseByUrlsMultiThreads(['https://www.example.com', 'https://www.example.org']));

Другие статьи