代码之家  ›  专栏  ›  技术社区  ›  Dennishofken

很长的加载时间php curl

  •  0
  • Dennishofken  · 技术社区  · 6 年前

    我正在尝试为我的战地1氏族创建一个网站,在其中一个页面上,我想显示我们的团队和他们的一些统计数据。

    This API允许我请求所需的内容,我决定使用php curl请求在我的站点上获取这些数据。这一切都很好,但速度非常慢,有时甚至达到了php的最大30秒。

    这是我的密码

    <?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']);
        }
    ?>
    

    我不知道为什么速度会这么慢,是因为我在本地主机上使用xamp,还是因为请求正在通过循环?

    提前感谢

    1 回复  |  直到 4 年前
        1
  •  2
  •   hanshenrik    6 年前

    你的循环一点都没有优化,我相信如果你优化了你的循环代码,你的代码可以运行得更快。您可以在每次迭代中创建和删除curl句柄,当您可以在每个播放器上重复使用相同的curl句柄时(这将使用更少的cpu并更快),您不使用压缩传输(启用压缩可能会使传输更快),最重要的是,您可以按顺序运行api调用,我相信如果您并行执行api请求,加载速度会快得多。此外,您没有对psnid进行urlencode,这可能是一个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\u编码),并行运行api请求和从db下载结果,并且在运行清理例程之前尝试断开客户端的连接,它可能会运行得更快。

    此外,如果mysqli\u fetch\u assoc()导致数据库的往返速度较慢,那么用mysqli\u fetch\u all()替换它可能会更快

    此外,可能比这快得多的是每分钟(或每10秒)运行一次cronjob它缓存结果,并向客户端显示缓存的结果。(即使api调用延迟,客户端页面负载也不会受到任何影响。)