0

我正在尝试使用“foreach”和数组循环一些函数。但是获取信息需要很长时间。是否可以同时运行所有数组循环元素?

ini_set("max_execution_time", 0);
function bhttpGet($burl)
{
    global $data;
    global $makaronas;
    global $makaronas2;
    $data = array("clientType" => "Android", "os" => "21", "screenType" => "xxhdpi", "version" => "3");                                                                    
    $data_string = json_encode($data);  
    $bch = curl_init();  

    curl_setopt($bch,CURLOPT_URL,$burl);
    curl_setopt($bch,CURLOPT_RETURNTRANSFER,true);
    curl_setopt($bch,CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($bch,CURLOPT_HEADER, false);
    curl_setopt($bch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($bch, CURLOPT_HEADER, 1);
    curl_setopt($bch, CURLOPT_RETURNTRANSFER, 1);

    curl_setopt($bch, CURLOPT_HTTPHEADER, array(
    'Accept-Language: en',
    'Content-Type: application/json; charset=UTF-8',
    'User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.0.2; HTC One Build/LRX22G)',
    'Host: mobileapi.turkishairlines.com',
    'Connection: Keep-Alive',
    'Accept-Encoding: gzip',
    'Cookie: JSESSIONID=5096E068E5B2E11E4EC96A6B725C5BB1; AWSELB=A3F31BC902ED4282BBCBA2D31E20E7210081D104D0AC59E7291F2B1692E6E27BB90F1D78BBC7CFBAD0D14DA4FFA5A59F223573F1C428362BCD544E72A28094F07742E08B3292F74F8BE17859D515D4392E4D9C052C'
    ));

    $result = curl_exec($bch);
    curl_close($bch);
    preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $result, $matches);
    $cookies = array();
    foreach($matches[1] as $item) {
        parse_str($item, $cookie);
        $cookies = array_merge($cookies, $cookie);
    }
    $makaronas = $cookies['JSESSIONID'];
    $makaronas2 = $cookies['AWSELB'];
}

function httpGet($url){
    global $makaronas3;
    global $makaronas4;
    $ch = curl_init();  

    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Accept-Language: en',
    'User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.0.2; HTC One Build/LRX22G)',
    'Host: mobileapi.turkishairlines.com',
    'Connection: Keep-Alive',
    'Accept-Encoding: gzip',
    "Cookie: JSESSIONID={$makaronas3}; AWSELB={$makaronas4}"

    ));
    $output2=curl_exec($ch);
    curl_close($ch);
 }

 function chttpGet($kurl){
    global $makaronas3;
    global $makaronas4;
    global $output3;
    $kch = curl_init();  

    curl_setopt($kch,CURLOPT_URL,$kurl);
    curl_setopt($kch,CURLOPT_RETURNTRANSFER,true);
    curl_setopt($kch,CURLOPT_SSL_VERIFYPEER, false); 
    curl_setopt($kch, CURLOPT_HTTPHEADER, array(
    'Accept-Language: en',
    'User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.0.2; HTC One Build/LRX22G)',
    'Host: mobileapi.turkishairlines.com',
    'Connection: Keep-Alive',
    'Accept-Encoding: gzip',
    "Cookie: JSESSIONID={$makaronas3}; AWSELB={$makaronas4}"
    ));

    $output3=curl_exec($kch);
    curl_close($kch);
}

function between($src,$start,$end){
    $txt=explode($start,$src);
    $txt2=explode($end,$txt[1]);
    return trim($txt2[0]);
  }
$departuredatearray= array("01.08.2016","02.08.2016","03.08.2016","04.08.2016","05.08.2016","06.08.2016","07.08.2016","08.08.2016","09.08.2016","10.08.2016","11.08.2016","12.08.2016","13.08.2016","14.08.2016","15.08.2016","16.08.2016","17.08.2016","18.08.2016","19.08.2016","20.08.2016","21.08.2016","22.08.2016","23.08.2016","24.08.2016","25.08.2016","26.08.2016","27.08.2016","28.08.2016","29.08.2016","30.08.2016","31.08.2016");

    foreach ($departuredatearray as $lopas) {
    $initialize="https://mobileapi.turkishairlines.com/init.json";
    $initialize2 = "https://mobileapi.turkishairlines.com/booking/internationalFlights.json?cabinType=economy&adultCount=1&childCount=0&infantCount=0&isOneWay=true&departureAirportCode=VNO&arrivalAirportCode=IST&flightDate={$lopas}&isReturn=false";
    $initialize3 = "https://mobileapi.turkishairlines.com/booking/internationalFare.json?departureFlightIndex=0&returnFlightIndex=-1&isDeparturePromotion=false&isReturnPromotion=false";
$mano=bhttpget($initialize);
echo "$mano";
$makaronas3=$makaronas;
$makaronas4=$makaronas2;
$mano2=httpget($initialize2);

echo "$mano2";
$mano4 = chttpget($initialize3);

echo "$mano4";
echo "<BR>";
echo "<table border='1' align='center' style='text-align:center;'>";
    echo "<tr>";
        echo "<td>flight Number</td>";
        echo "<td>departure Airport Code</td>";
        echo "<td>arrival Airport Code</td>";
        echo "<td>departure Date</td>";
        echo "<td>departure Time</td>";
        echo "<td>arrival Date</td>";
        echo "<td>arrival Time</td>";
        echo "<td>duration</td>";
        echo "<td>total Price</td>";
        echo "<td>Curency</td>";
    echo "</tr>";
    echo "<tr>";
        echo "<td>";
        echo between($output3, '"flightNumber":"', '","departureAirportCode');
        echo "</td>";
        echo "<td>";
        echo between($output3, 'departureAirportCode":"', '","departureAirportName');
        echo "</td>";
        echo "<td>";
        echo between($output3, 'arrivalAirportCode":"', '","arrivalAirportName');
            echo "</td>";          
            echo "<td>";
            echo between($output3, 'departureDate":"', '","formattedDepartureDate');
            echo "</td>";   
            echo "<td>";
            echo between($output3, 'departureTime":"', '","arrivalDate');
            echo "</td>";   
            echo "<td>";
            echo between($output3, 'arrivalDate":"', '","formattedArrivalDate');
            echo "</td>"; 
            echo "<td>";
            echo between($output3, 'arrivalTime":"', '","duration');
            echo "</td>";  
            echo "<td>";
            echo between($output3, 'duration":"', '","stopTimeAfterArrival');
            echo "</td>";
            echo "<td>";
            echo between($output3, 'totalPrice":"', '","currency":"');
            echo "</td>";
            echo "<td>";
            echo between($output3, 'currency":"', '","totalTax');
            echo "</td>";

echo "</table>";
};
4

2 回答 2

2

您的问题是每次迭代foreach花费在 HTTP 请求上的时间。这是 API 延迟的问题,通常通过同时处理部分 HTTP 请求来解决。

例如,如果每个 HTTP 请求需要 3 秒才能完成,并且您可以同时处理 10 个 HTTP 请求,那么您的脚本大约快了10 倍

 100 Requests w/o concurrency (3 seconds each, 1 at a time) = 300 seconds
 100 Requests w/ concurrency (3 seconds each, 10 at a time) =  30 seconds

有一种很好的方法可以将 HTTP 请求并行化到一curl_multi*组函数中。它内置在 cURL 库中,非常易于使用。

教程: http ://www.phpied.com/simultaneuos-http-requests-in-php-with-curl/

PHP 手册: http: //php.net/manual/en/function.curl-multi-exec.php

重要的是要注意,您可以并且应该同时执行的 HTTP 请求的数量确实存在限制。curl_multi*默认为 10 个并发 HTTP 请求,这是一个很好的限制。增加此限制必须谨慎、尊重和负责任地进行,这可能会对其他服务造成严重损害。

要增加此限制(例如,如果您向自己的服务器发出请求),您可以使用curl_multi_setoptCURLMOPT_MAXCONNECTS选项

$new_limit = 15;
curl_multi_setopt ( $mh, CURLMOPT_MAXCONNECTS, $new_limit );

另请注意,除非您的服务器/互联网连接出现问题,否则您不能使单个请求的速度比现在更快。并发不会帮助您使单个请求更快(只​​是想我会说清楚)。

如果您愿意,您也可以使用线程,但我认为内置 cURL 方法将是最快、最简单且最易于维护的,因为您现有的代码

于 2016-04-22T07:28:11.963 回答
0

在 @edhurtig 开始的同一思路中,您可能想看看PHP 中的线程。我认为您以某种方式错误地说明了问题。您需要执行几个独立的请求,并且它们不需要是串行的,这发生在 foreach 循环中。可以通过为每个请求打开一个新线程来进行并行 API 调用,从而并行执行它们。

于 2016-04-22T07:46:30.930 回答