勉強したことのメモ

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

  関連記事

PHP8系で追加されたJIT(Just-In-Time)の設定方法

PHP8系でOPcacheの拡張機能としてJIT(Just-In-Time)とい ...

PHPでis_fileとfile_existsについて

ファイルの存在チェックを行う際に、file_exists関数を 使用していたが、 ...