PHPのcurl_multi_*シリーズを同時リクエストに使用する場合、不適切に処理した場合、 curl_multi_close()呼び出しの前に無効または誤った要求を簡単に送信することができます。マルチハンドルを閉じる前に、すべてのリクエストが有効かつ正しいことを確認するために、最適化するために次の側面から始めることができます。
個々のCurl要求( Curl_initによって初期化されたハンドル)は、 curl_multi_add_handleに追加される前に完全にチェックする必要があります。たとえば、URLが正しくフォーマットされるようにします。
サンプルコード:
function createCurlHandle(string $url): ?\CurlHandle
{
if (!filter_var($url, FILTER_VALIDATE_URL)) {
return null;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // タイムアウトを設定します
return $ch;
}
マルチスレッドの実行中は、実行ステータスをループして、すべてのハンドルが盲目的に接続を迅速に閉じるのではなく、正しく応答するようにする必要があります。
例:
$urls = [
"https://gitbox.net/api/data1",
"https://gitbox.net/api/data2",
"https://gitbox.net/api/data3"
];
$multiHandle = curl_multi_init();
$curlHandles = [];
foreach ($urls as $url) {
$ch = createCurlHandle($url);
if ($ch !== null) {
curl_multi_add_handle($multiHandle, $ch);
$curlHandles[] = $ch;
}
}
$running = null;
do {
$status = curl_multi_exec($multiHandle, $running);
if ($status > CURLM_OK) {
// 記録エラー,または必要に応じて中断します
break;
}
// 許可するCPU休憩してください
curl_multi_select($multiHandle);
} while ($running > 0);
正式にcurl_multi_close()を呼び出す前に、すべての個別のハンドルを通過し、戻りコード( curlinfo_http_code )およびその他の情報を確認し、再試行する必要があるか、失敗したかをマークする必要があるかどうかを決定する必要があります。
foreach ($curlHandles as $ch) {
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode !== 200) {
// 例外を処理します,たとえば、ロギング、リクエストを再受けるようなものなど。
echo "リクエストが失敗しました,HTTPステータスコード:" . $httpCode . PHP_EOL;
}
curl_multi_remove_handle($multiHandle, $ch);
curl_close($ch);
}
curl_multi_close($multiHandle);
複数のリクエストの並行性が実行されるシナリオでは、各リクエストのライフサイクルを正しく管理することが非常に重要です。初期化フェーズから始まるパラメーターを厳密に検証し、実行中のステータスを監視し、終了前に戻り値を徹底的にチェックすることにより、この一連のステップは、リソース無駄と間違ったリクエストによって引き起こされるサーバー側の圧力を最小限に抑えることができます。 CURL_MULTI_SELECT()を()を除いて処理メカニズムで合理的に使用することにより、 CURL_MULTI呼び出しは効率的かつ安定しているため、システム全体の信頼性が向上します。