我可以对同一个URL执行多个并行cURL吗


Can I execute a multiple parallel cURL against the same URL?

我需要使用cURL并行执行多个请求,但我需要对同一个URL执行。

这是因为作为一个SOAP Web服务,我有一个唯一的URL,但我会发送不同的头来接收我需要的多个响应。

我试图制作一个curl_multi_exec,但我var_dump$channels数组,我只收到1个,我认为这是因为curl正在重新使用连接,所以我尝试了CURLOPT_FRESH_CONNECT和CURLOPT-FORBID_REUSE,但没有成功。

知道如何实现吗?

    $url = "http://myURL.com/SOAPWebservice.svc";
    $stationIds = array(207,303,305,195,204,205);//5,10);
    // 207,303,305,195,204,205,206,212,306,196,193,194,307,312,197,198,199,200,201,202,203,302,308,367,304,309,310,311
    $multi = curl_multi_init();
    $channels = array();
    // Loop through the URLs, create curl-handles
    // and attach the handles to our multi-request
    foreach ($stationIds as $stationId)
    {
        $soap_request =
            '<?xml version="1.0" encoding="UTF-8"?>
                <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns6930="http://tempuri.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                    <SOAP-ENV:Body>
                        <GetStationById xmlns="http://tempuri.org/">
                            <StationID>' . $stationId . '</StationID>
                            <CityID>5</CityID>
                        </GetStationById>
                    </SOAP-ENV:Body>
                </SOAP-ENV:Envelope>';
        $header = array(
            "Content-type: text/xml;charset='"utf-8'"",
            "Accept: text/xml",
            "Cache-Control: no-cache",
            "Pragma: no-cache",
            "SOAPAction: '"http://tempuri.org/IBLLStation/GetStationById'"",
            "Content-length: ".strlen($soap_request),
        );

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,            $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt($ch, CURLOPT_POST,           true );
        curl_setopt($ch, CURLOPT_POSTFIELDS,     $soap_request);
        curl_setopt($ch, CURLOPT_HTTPHEADER,     $header);
        curl_setopt($ch, CURLOPT_FRESH_CONNECT,     TRUE);
        curl_setopt($ch, CURLOPT_FORBID_REUSE,     TRUE);
        curl_multi_add_handle($multi, $ch);
        $channels[$url] = $ch;
    }
    // While we're still active, execute curl
    $active = null;
    do {
        $mrc = curl_multi_exec($multi, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    while ($active && $mrc == CURLM_OK) {
        // Wait for activity on any curl-connection
        if (curl_multi_select($multi) == -1) {
            continue;
        }
        // Continue to exec until curl is ready to
        // give us more data
        do {
            $mrc = curl_multi_exec($multi, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
    // Loop through the channels and retrieve the received
    // content, then remove the handle from the multi-handle
    $StationsLastContact = "";
    // echo print_r($channels,TRUE);
    foreach ($channels as $channel) {
        $response = curl_multi_getcontent($channel);
        $startsAt           = strpos($response, "StationLastContact>") + strlen("StationLastContact>");
        $endsAt             = strpos($response, "<", $startsAt);
        $StationLastContact = substr($response, $startsAt, $endsAt - $startsAt);
        $StationLastContact .= "<br />";
        $StationsLastContact .= $StationLastContact;
        curl_multi_remove_handle($multi, $channel);
    }
    // Close the multi-handle and return our results
    curl_multi_close($multi);
    die($StationsLastContact);

检查下面的代码是否有效。我刚刚使用了一个处理程序数组。

var_dump($ch);
array(6) {
  [207]=>
  resource(3) of type (curl)
  [303]=>
  resource(4) of type (curl)
  [305]=>
  resource(5) of type (curl)
  [195]=>
  resource(6) of type (curl)
  [204]=>
  resource(7) of type (curl)
  [205]=>
  resource(8) of type (curl)
}

    $url = "http://myURL.com/SOAPWebservice.svc";
    $stationIds = array(207,303,305,195,204,205);//5,10);
    // 207,303,305,195,204,205,206,212,306,196,193,194,307,312,197,198,199,200,201,202,203,302,308,367,304,309,310,311
    $multi = curl_multi_init();
    $channels = array();
    // Loop through the URLs, create curl-handles
    // and attach the handles to our multi-request
    foreach ($stationIds as $stationId)
    {
        $soap_request =
            '<?xml version="1.0" encoding="UTF-8"?>
                <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns6930="http://tempuri.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                    <SOAP-ENV:Body>
                        <GetStationById xmlns="http://tempuri.org/">
                            <StationID>' . $stationId . '</StationID>
                            <CityID>5</CityID>
                        </GetStationById>
                    </SOAP-ENV:Body>
                </SOAP-ENV:Envelope>';
        $header = array(
            "Content-type: text/xml;charset='"utf-8'"",
            "Accept: text/xml",
            "Cache-Control: no-cache",
            "Pragma: no-cache",
            "SOAPAction: '"http://tempuri.org/IBLLStation/GetStationById'"",
            "Content-length: ".strlen($soap_request),
        );

        $ch[$stationId] = curl_init();
        curl_setopt($ch[$stationId], CURLOPT_URL,            $url);
        curl_setopt($ch[$stationId], CURLOPT_RETURNTRANSFER, true );
        curl_setopt($ch[$stationId], CURLOPT_POST,           true );
        curl_setopt($ch[$stationId], CURLOPT_POSTFIELDS,     $soap_request);
        curl_setopt($ch[$stationId], CURLOPT_HTTPHEADER,     $header);
        curl_setopt($ch[$stationId], CURLOPT_FRESH_CONNECT,     TRUE);
        curl_setopt($ch[$stationId], CURLOPT_FORBID_REUSE,     TRUE);
        curl_multi_add_handle($multi, $ch[$stationId]);
    }
    // While we're still active, execute curl
    $active = null;
    do {
        $mrc = curl_multi_exec($multi, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    while ($active && $mrc == CURLM_OK) {
        // Wait for activity on any curl-connection
        if (curl_multi_select($multi) == -1) {
            continue;
        }
        // Continue to exec until curl is ready to
        // give us more data
        do {
            $mrc = curl_multi_exec($multi, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
    // Loop through the channels and retrieve the received
    // content, then remove the handle from the multi-handle
    $StationsLastContact = "";
    // echo print_r($channels,TRUE);
    foreach ($ch as $channel) {
        $response = curl_multi_getcontent($channel);
        $startsAt           = strpos($response, "StationLastContact>") + strlen("StationLastContact>");
        $endsAt             = strpos($response, "<", $startsAt);
        $StationLastContact = substr($response, $startsAt, $endsAt - $startsAt);
        $StationLastContact .= "<br />";
        $StationsLastContact .= $StationLastContact;
        curl_multi_remove_handle($multi, $channel);
    }
    // Close the multi-handle and return our results
    curl_multi_close($multi);
    die($StationsLastContact);