curl_multi_*一連の関数を使用して同時リクエストを作成する場合、通常、複数のCurlハンドルを開き、統一された管理のためにCurl_multiハンドルに追加します。
curl_multi_closeを呼び出してリソースをリリースする前に、すべてのリクエストが正しく完了したことを確認するために、各リクエストの実行ステータスを合理的に検出する必要があります。この記事では、この要件を達成するための標準的で信頼できる方法について説明します。
通常、次の手順に従って複数のリクエストを処理します。
複数のカール別のハンドルを初期化します。
これらのハンドルをcurl_multiハンドルに追加します。
curl_multi_execを使用してリクエストを継続的に実行します。
curl_multi_selectを使用してcurl_multi_execと協力して、リクエストが完了したかどうかを検出します。
完了した要求ハンドルを1つずつ削除します。
すべてのリクエストが完了していることを確認してから、 curl_multi_closeに電話してください。
複数のURLをリクエストする必要があると仮定して、完全な例を次に示します(ここでは、 https://gitbox.net/example1およびhttps://gitbox.net/example2を例として使用します):
<?php
// 初期化 cURL multi ハンドル
$multiHandle = curl_multi_init();
// それぞれを保存します cURL ハンドル的数组
$curlHandles = [];
// 要求する URL リスト
$urls = [
'https://gitbox.net/example1',
'https://gitbox.net/example2',
];
// それぞれを作成して追加します cURL ハンドル
foreach ($urls as $i => $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multiHandle, $ch);
$curlHandles[$i] = $ch;
}
// 埋め込む multi 聞く
$running = null;
do {
$status = curl_multi_exec($multiHandle, $running);
// 防ぐ CPU アイドル
if ($status == CURLM_OK) {
curl_multi_select($multiHandle);
} else {
break;
}
// 检查是否有已完成的聞く
while ($info = curl_multi_info_read($multiHandle)) {
if ($info['msg'] == CURLMSG_DONE) {
// 获取完成的ハンドル
$completedHandle = $info['handle'];
// 返されたコンテンツを取得します
$response = curl_multi_getcontent($completedHandle);
// 返されたデータはここで処理できます
echo "聞く完成,データの長さを返します:" . strlen($response) . PHP_EOL;
// 移除并关闭已完成的ハンドル
curl_multi_remove_handle($multiHandle, $completedHandle);
curl_close($completedHandle);
}
}
} while ($running > 0);
// 最後の終わり multi ハンドル
curl_multi_close($multiHandle);
curl_multi_exec :同時リクエストの実行を促進し、まだ実行されている接続の数を返します。
curl_multi_select :CPUリソースの無駄を減らすためにアクティブな接続をブロックして待つために使用されます。
curl_multi_info_read :要求が完了したかどうかを検出し、完了したハンドルを一度に処理できるかどうかを検出します。
curl_multi_closeは、$ running == 0で、すべてのクローンハンドルが削除および閉じられている場合にのみ呼び出されます。
多くのリクエストがある場合は、いくつかの要求が長い間詰まらないようにタイムアウトメカニズムを追加することをお勧めします。
curl_multi_selectは時々 -1を返します。この場合、デッドループを防ぐために小さな待機にusleep()を使用する必要があります。
if (curl_multi_select($multiHandle) == -1) {
usleep(100);
}
これにより、スクリプトがより堅牢になります。
curl_multi_closeを使用する前に、すべてのサブレクエストが完了して正しくクリーニングされていることを確認することです。上記のパターンは、一般的で推奨される標準的な慣行です。
curl_multi_*シリーズの動作を理解することで、より効率的で安定した同時ネットワークリクエストコードの作成に役立ちます!