减少PHP的执行时间


Reduce PHP execution time

我有这个PHP脚本,通过API从游戏高分检索信息。问题是,对于每个玩家来说,这需要半秒左右的时间,随着用户数量不断增加,加载页面需要50秒,这是非常长的时间。有什么方法可以减少加载时间,或者我必须在检索数据后存储数据,并且每30分钟左右更新一次。

这是代码:

    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("/['n'r]/", ",", $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);
    }

你不应该依赖第三方网站来构建你自己的内容。如果你的服务器发出太多请求,他们甚至可以阻止你;当几个访问者同时打开一个页面时,例如

相反,您应该调度后台作业(在Linux上使用cron或在Windows上使用任务调度器)定期获取记录(或者如果可能的话仅更新记录)并在您自己的数据库中添加/替换这些记录。

然后你可以从你自己的数据库提供内容,这将是即时的。您还可以控制您向外部网站发出的请求数量,从而降低最终被列入黑名单的风险。

你可以同时做几个卷,参见http://php.net/manual/en/function.curl-multi-init.php。比如:

<?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("/['n'r]/", ",", $html));
      $totalCombat += calcaulateScore($oneLine);
    }
    curl_multi_remove_handle($mh, $c);
}
curl_multi_close($mh);