勉強したことのメモ.

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でOGPタグ(metaタグ)を簡単に取得できる「OpenGraph.php」の利用方法
PHPでOGPタグ(metaタグ)を簡単に取得できる「OpenGraph.php」の利用方法

PHPでOGPタグ(metaタグ)を取得する際、file_get_content ...

PHPの配列でキーの最大値を取得
PHPの配列でキーの最大値を取得

PHPの配列でキーの最大値を取得したかった。以下で対応する。 $test = a ...

PHPで引数の先頭に&(アンパサンド)をつける参照渡し(リファレンス渡し)について
PHPで引数の先頭に&(アンパサンド)をつける参照渡し(リファレンス渡し)について

他社が作成されたPHPのソースコードを拝見していると関数の引数の頭に&( ...

【2024年版】PHPMailerでGmailのSMTPサーバを経由してメールを送信する方法
【2024年版】PHPMailerでGmailのSMTPサーバを経由してメールを送信する方法

だいぶ前に同じようなことをメモしたが、そちらの方法だと送信できずエラー内容を見た ...

PHPで住所や名前のテキストをランダム生成するライブラリFakerPHPの使い方
PHPで住所や名前のテキストをランダム生成するライブラリFakerPHPの使い方

PHPでランダムなデータを生成したい際に値段や点数等の数値やパスワード等のランダ ...