很长的加载时间php curl

时间:2018-04-26 21:15:47

标签: php curl

我试图为我的战场1战队建立一个网站,在其中一个网页上我想展示我们的团队和他们的一些统计数据。

This API允许我请求我需要的东西,我决定使用php curl请求在我的网站上获取这些数据。这一切都很好,但它超级慢,有时它甚至达到PHP的30s最大值。

这是我的代码

<?php
$data = $connection->query("SELECT * FROM bfplayers");
while($row = mysqli_fetch_assoc($data)){
$psnid = $row['psnid'];


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://battlefieldtracker.com/bf1/api/Stats/BasicStats?platform=2&displayName=".$psnid);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

$headers = [
    'TRN-Api-Key: MYKEY',
];

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);

print($result['profile']['displayName']);
    }
?>

我不知道它为什么这么慢,是因为我在localhost上使用xamp还是因为请求正在循环?

提前致谢

1 个答案:

答案 0 :(得分:2)

你的循环没有丝毫优化,我相信如果你优化了循环代码,你的代码可以更快地运行。你可以在每次迭代时创建和删除curl句柄,当你可以在每个播放器上重复使用相同的curl句柄时(这将使用更少的cpu并且更快),你不使用压缩传输(启用压缩可能会使传输更快),最重要的是,你顺序运行api调用,我相信如果你并行执行api请求,它会加载更快。另外,你没有urlencode psnid,这可能是一个bug。试试这个

<?php
$cmh = curl_multi_init ();
$curls = array ();
$data = $connection->query ( "SELECT * FROM bfplayers" );

while ( ($row = mysqli_fetch_assoc ( $data )) ) {
    $psnid = $row ['psnid'];
    $tmp = array ();
    $tmp [0] = ($ch = curl_init ());
    $tmp [1] = tmpfile ();
    $curls [] = $tmp;
    curl_setopt_array ( $ch, array (
            CURLOPT_URL => "https://battlefieldtracker.com/bf1/api/Stats/BasicStats?platform=2&displayName=" . urlencode ( $psnid ),
            CURLOPT_ENCODING => '',
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_HTTPHEADER => array (
                    'TRN-Api-Key: MYKEY' 
            ),
            CURLOPT_FILE => $tmp [1] 
    ) );
    curl_multi_add_handle ( $cmh, $ch );
    curl_multi_exec ( $cmh, $active );
}
do {
    do {
        $ret = curl_multi_exec ( $cmh, $active );
    } while ( $ret == CURLM_CALL_MULTI_PERFORM );
    curl_multi_select ( $cmh, 1 );
} while ( $active );
foreach ( $curls as $curr ) {
    fseek ( $curr [1], 0, SEEK_SET ); // https://bugs.php.net/bug.php?id=76268
    $response = stream_get_contents ( $curr [1] );
    $result = json_decode ( $response,true );
    print ($result ['profile'] ['displayName']) ;
}
// the rest is just cleanup, the client shouldn't have to wait for this
// OPTIMIZEME: apache version of fastcgi_finish_request() ?
if (is_callable ( 'fastcgi_finish_request' )) {
    fastcgi_finish_request ();
}
foreach ( $curls as $curr ) {
    curl_multi_remove_handle ( $cmh, $curr [0] );
    curl_close ( $curr [0] );
    fclose ( $curr [1] );
}
curl_multi_close ( $cmh );
  • 它并行运行所有api调用,并使用传输压缩(CURLOPT_ENCODING),并与从db下载结果并行运行api请求,并尝试在运行清理例程之前断开客户端,它可能运行得更快。

另外,如果mysqli_fetch_assoc()导致你的数据库慢速往返,用mysqli_fetch_all()替换它可能会更快

另外,可能比这更快的事情是,每分钟(或每10秒?)运行一次cronjob来缓存结果,并向客户端显示缓存结果。 (即使api调用滞后,客户端页面加载也不会受到影响。)