勉強したことのメモ

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

  関連記事

Stripe Checkoutにてクレジットカード決済の際に3Dセキュア対応にする方法
Stripe Checkoutにてクレジットカード決済の際に3Dセキュア対応にする方法

先日Stripe Checkoutを用いたクレジットカード決済機能についてメモし ...

PHPでテンプレートPDFに動的に文字や数値を追記し出力する方法(TCPDF&FPDI)
PHPでテンプレートPDFに動的に文字や数値を追記し出力する方法(TCPDF&FPDI)

請求書や領収書のテンプレートがあり、そちらに対して動的に文字・数値を追記し出力さ ...

PHPのintval
PHPのintval

intvalという見たこと無い関数があったのでメモ。 ■リファレンス http: ...

PHPでルーティング用ライブラリ「AltoRouter」の利用方法
PHPでルーティング用ライブラリ「AltoRouter」の利用方法

PHPフレームワークのCodeIgniterを勉強していた際にルーティング機能が ...

CodeIgniter4でCronを実行する方法
CodeIgniter4でCronを実行する方法

CodeIgniter4.4.4で特定の処理をCronで自動実行させたい。以下に ...