减少PHP执行时间

I have this PHP script which retrieves information via an API from a games high scores. The problem is that for each player it takes around half a second and with the amount of users continuing to add up to more than 100 it takes about 50 seconds for the page to load, which is very long. Is there any way I can reduce the loading time, or do I have to store the data after I retrieve it and only update it every 30 minutes or so.

This is the code:

    for ($i = 0; $i <= $totalMembers - 1; $i++) {
        $currentLine = $lines[$i];
        $Data = explode("\t", $currentLine);
        $nameParsed = rawurlencode($Data[1]);

        $c = curl_init('http://services.runescape.com/m=hiscore_oldschool/index_lite.ws?player=' . $nameParsed);
        curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($c, CURLOPT_TIMEOUT, 0);

        $html = curl_exec($c);
        //$htmlTrimmed = trim($html);
        $oneLine = trim(preg_replace("/[
]/", ",", $html));

        if (curl_error($c))
            die(curl_error($c));

        // Get the status code
        $status = curl_getinfo($c, CURLINFO_HTTP_CODE);
        if ($status != 404){
            $userInfo = explode(",", $oneLine);

            $Base = 0.25 * ($userInfo[7] + $userInfo[13] + floor($userInfo[19]/2));
            $Melee = 0.325 * ($userInfo[4] + $userInfo[10]);
            $Range = 0.325 * (floor($userInfo[16]/2) + $userInfo[16]);
            $Mage = 0.325 * (floor($userInfo[22]/2) + $userInfo[22]);
            $classLevel2 = max($Melee, $Range, $Mage);
            $Final = floor($Base + $classLevel2);
            $totalCombat += $Final;
        }
        curl_close($c);
    }

You can do several curls together async see http://php.net/manual/en/function.curl-multi-init.php. Something like:

<?php
function parseName($line) {
  $data = explode("\t", $line);
  return rawurlencode($data[1]);
} 

function calculateScore($line) {
  $userInfo = explode(",", $line);

  $Base = 0.25 * ($userInfo[7] + $userInfo[13] + floor($userInfo[19]/2));
  $Melee = 0.325 * ($userInfo[4] + $userInfo[10]);
  $Range = 0.325 * (floor($userInfo[16]/2) + $userInfo[16]);
  $Mage = 0.325 * (floor($userInfo[22]/2) + $userInfo[22]);
  $classLevel2 = max($Melee, $Range, $Mage);
  return floor($Base + $classLevel2);
}   

$curls = array();
$mh = curl_multi_init();

for ($i = 0; $i < $totalMembers; $i++) {
    $curls[$i] = curl_init('http://services.runescape.com/m=hiscore_oldschool/index_lite.ws?player=' . parseName($lines[$i]));
    curl_setopt($curls[$i], CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curls[$i], CURLOPT_TIMEOUT, 0);
    curl_multi_add_handle($mh, $curls[$i]);
}   

$running = null;
do {
  curl_multi_exec($mh, $running);
} while($running > 0);

foreach($curls as $id => $c) {
    $status = curl_multi_getinfo($c, CURLINFO_HTTP_CODE);

    if ($status != 404){
      $html = curl_multi_getcontent($c);
      $oneLine = trim(preg_replace("/[
]/", ",", $html));
      $totalCombat += calcaulateScore($oneLine);
    }
    curl_multi_remove_handle($mh, $c);
}
curl_multi_close($mh);

You should not rely on the third-party web-site for building your own content. They could even block you if your server makes too many requests; when several visitors open the page around the same time for example.

Instead, you should schedule a background job (using cron on Linux or task scheduler on Windows) to periodically get the records (or only updated ones if possible) and add / replace these in your own database.

Then you can serve the content from your own database which will be instantaneous. And you also control how many requests you are making to the external web-site, reducing the risk of ending up on their blacklist.