对同一API端点执行多个同时POST调用

时间:2017-07-25 17:02:20

标签: php pthreads guzzle php-pthread

我正在尝试执行多个POST REST调用。 捕获 :同时执行多个POST调用。我完全清楚并且已经与图书馆guzzle合作,但我还没有想过要正确地做这件事。我可以异步执行GET次调用,但POST次调用不会处于同一级别。然后我遇到了pthreads并且我阅读了文档并且对如何开始它有点困惑。我已使用php扩展名编译pthreads

有人可以建议如何同时执行多个POST来电,并能够收集回复以供日后操作吗?

以下是循环和等待的基本实现。整体来说非常缓慢。

$postDatas = [
    ['field' => 'test'],
    ['field' => 'test1'],
    ['field' => 'test2'],
];

foreach ($postDatas as $postData) {
    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_URL            => "https://www.apisite.com",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING       => "",
        CURLOPT_MAXREDIRS      => 10,
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST  => "POST",
        CURLOPT_POSTFIELDS     => json_encode($postData),
        CURLOPT_HTTPHEADER     => [
            "cache-control: no-cache",
            "connection: keep-alive",
            "content-type: application/json",
            "host: some.apisite.com",
        ],
    ));

    $response = curl_exec($curl);
    $err      = curl_error($curl);

    curl_close($curl);

    if ($err) {
        echo "cURL Error #:" . $err;
    } else {
        echo $response;
    }
}

1 个答案:

答案 0 :(得分:1)

如果任务减少到使用API​​,那么您可能需要使用http://php.net/manual/ru/function.curl-multi-exec.php

public function getMultiUrl() {
    //If the connections are very much split the queue into parts
    $parts = array_chunk($this->urlStack, self::URL_ITERATION_SIZE , TRUE);

    //base options
    $options = [
        CURLOPT_USERAGENT => 'MyAPP',
        CURLOPT_HEADER => false,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
    ];

    foreach ($parts as $urls) {
        $mh = curl_multi_init();
        $active = null;
        $connects = [];
        foreach ($urls as $i => $url) {
            $options[CURLOPT_POSTFIELDS] = $url['postData']; 
            $connects[$i] = curl_init($url['queryUrl']);

            curl_setopt_array($connects[$i], $options);
            curl_multi_add_handle($mh, $connects[$i]);
        }

        do {
            $status = curl_multi_exec($mh, $active);
            $info = curl_multi_info_read($mh);
            if (false !== $info) {
                var_dump($info);
            }
        } while ($status === CURLM_CALL_MULTI_PERFORM || $active);

        foreach ($connects as $i => $conn) {
            $content = curl_multi_getcontent($conn);
            file_put_contents($this->dir . $i, $content);
            curl_close($conn);
        }
    }
}