勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

PHPで外部のAPIにリクエストする際に並列処理(非同期実行)する方法

  PHP

あるシステムからPHPで外部のAPIにリクエストしたかった。ただ、複数回リクエストする必要があり、curlもしくはfile_get_contentsをループで回すとページの表示速度がかなり遅くなった。curl_multi_initを用いて並列処理(非同期実行)することで改善されたので以下に対応方法をメモ。

 

対応方法

ソースコード

<?php
$url_list = array(
    'https://api.com/?code=1',
    'https://api.com/?code=2',
    'https://api.com/?code=3',
);

$result = getMultiContents($url_list);
var_dump($result);

function getMultiContents( $url_list ) {

    $mh = curl_multi_init();

    $ch_list = array();

    foreach( $url_list as $url ) {
        $ch_list[$url] = curl_init($url);
        curl_setopt($ch_list[$url], CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch_list[$url], CURLOPT_TIMEOUT, 1);
        curl_multi_add_handle($mh, $ch_list[$url]);
    }

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

    foreach( $url_list as $key => $url ) {
        $results[$key]["content"] = curl_multi_getcontent($ch_list[$url]);

        curl_multi_remove_handle($mh, $ch_list[$url]);
        curl_close($ch_list[$url]);
    }

    curl_multi_close($mh);

    return $results;
}

注意点

上記ソースコードというよりもAPI側の問題になるかとは思うが、APIリクエストのレートリミットに注意すること。

速度について

郵便番号のAPIに1ページで3回分リクエストを試したところ、実行速度は並列処理の場合は約0.3秒、普通にループを回した場合は約1秒という結果になった。

また、5回ずつ試したが並列処理の場合は0.27~0.3秒と実行速度の幅が少なく安定していたが、ループの場合は0.8~1.4秒と幅がやや多めと不安定だった。

双方のサーバの回線の太さや混み合い具合によって変わってくるんだろうけどレートリミットの問題が解決できるのであれば並列処理する方が良さそう。

 

リファレンス

curl_multi_init

https://www.php.net/manual/ja/function.curl-multi-init.php

 

参考サイト

https://techblog.yahoo.co.jp/architecture/api1_curl_multi/

 - PHP

  関連記事

PHPでCSVを簡単に取り扱える「LeagueCSV(thephpleague / csv)」の利用方法
PHPでCSVを簡単に取り扱える「LeagueCSV(thephpleague / csv)」の利用方法

PHPでCSVファイルの書き込みや読み込みを行う際、バニラPHPで対応していたが ...

PHPで指定したカラーコードの反対色を計算し、カラーコードとして出力する方法
PHPで指定したカラーコードの反対色を計算し、カラーコードとして出力する方法

あるシステム内でユーザが指定したカラーコードをCSSで指定した上で出力するという ...

PHPで配列のキーの最大値を取得する方法
PHPで配列のキーの最大値を取得する方法

配列のキーに整数値が入っていて、その中から最大値を取得したいケースがあった。調べ ...

PHPで他サーバにFTP経由にてファイルをアップロードする方法
PHPで他サーバにFTP経由にてファイルをアップロードする方法

formで送信した内容をチェックした上で、他サーバにファイルをアップロードしたか ...

Codeigniter3で異なるデータベースを使用する
Codeigniter3で異なるデータベースを使用する

Codeigniterで2つのコンテンツがあって、それぞれ別のデータベースを使用 ...