PHPで外部のAPIにリクエストする際に並列処理(非同期実行)する方法
あるシステムから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
参考サイト
関連記事
-
-
PHPで「Call to undefined function mb_str_split()」エラーの対応方法
PHPにて「Fatal error: Uncaught Error: Call ...
-
-
TCPDF&FPDIでテンプレートPDFを使用し、複数ページのPDFを作成する方法
TCPDF&FPDIを用いて請求書PDFを発行するシステムがあった。請求 ...
-
-
PHPで「Warning: date(): It is not safe to…」エラーの対応方法
PHPでdate関数を使った際に「Warning: date(): It is ...
-
-
CodeIgniter3でCronを実行する方法
CodeIgniter3系で特定の処理をCronで自動実行したかった。以下に設定 ...
-
-
Opauthで「Please change the…」エラーの対応方法
Opauthを使用中に「Notice: Please change the va ...