PHPでCurl拡張機能を使用する場合、 Curl_multi_*関数は通常、複数の同時リクエストを処理するために使用されます。これらの機能は、特に複数のHTTP要求が同時に送信される場合、プログラムのパフォーマンスを大幅に改善できます。ただし、 curl_multi_close関数を使用する場合、一部の開発者は要求処理の干渉の問題に遭遇する可能性があり、要求が正しく完了したり、エラーを返したりしません。
この記事では、要求処理の干渉を回避し、いくつかの実用的なコードの例とソリューションを共有する方法について説明します。
PHPは、 CURL_MULTI_*関数を提供して、複数の同時CURL要求を実行します。主な機能は次のとおりです。
curl_multi_init() :curlマルチハンドルを初期化します。
curl_multi_add_handle() :複数のカールハンドルを1つの複数のハンドルに追加します。
curl_multi_exec() :すべてのcurlリクエストを実行します。
curl_multi_getContent() :curl要求のコンテンツを取得します。
curl_multi_remove_handle() :複数のハンドルからカールハンドルを削除します。
curl_multi_close() :すべてのcurlハンドルを閉じて、リソースをリリースします。
<?php
$multiHandle = curl_multi_init();
$urls = [
'https://gitbox.net/api/endpoint1',
'https://gitbox.net/api/endpoint2',
'https://gitbox.net/api/endpoint3'
];
$handles = [];
// 複数の要求ハンドルを初期化します
foreach ($urls as $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multiHandle, $ch);
$handles[] = $ch;
}
// リクエストを実行します
$running = null;
do {
curl_multi_exec($multiHandle, $running);
} while ($running);
// 応答データを取得します
foreach ($handles as $ch) {
$response = curl_multi_getcontent($ch);
echo $response . "\n";
curl_multi_remove_handle($multiHandle, $ch);
}
// ハンドルを閉じます
curl_multi_close($multiHandle);
?>
curl_multi_close関数は便利なクリーニング機能ですが、特にリクエストが完了しないときにcurl_multi_closeが呼び出された場合、要求処理の最後の段階で干渉することがあります。この干渉により、一部の要求が正しく完了できない場合や、受信した応答が不完全である可能性があります。
同時リクエストの完了時間は一貫していません。リクエストの異なる応答時間が異なるため、 Curl_multi_closeが呼び出された場合、一部の要求が完了していないため、リクエストは事前に閉じられます。
リソースリリースの問題:場合によっては、リソースが完全にリリースされる前にcurl_multi_closeを呼び出すと、他の要求に影響を与えるか、接続が切断される可能性があります。
curl_multi_close関数の要求処理における干渉を回避するために、次の戦略を採用できます。
curl_multi_closeを呼び出す前に、すべてのリクエストが完了していることを確認してください。 curl_multi_execによって返される実行ステータスをチェックすることにより、すべてのリクエストが完了したかどうかを確認できます。 curl_multi_closeは、すべての要求が処理された場合にのみ呼び出す必要があります。
<?php
$multiHandle = curl_multi_init();
$urls = [
'https://gitbox.net/api/endpoint1',
'https://gitbox.net/api/endpoint2',
'https://gitbox.net/api/endpoint3'
];
$handles = [];
// 複数の要求ハンドルを初期化します
foreach ($urls as $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multiHandle, $ch);
$handles[] = $ch;
}
// リクエストを実行します
$running = null;
do {
$mrc = curl_multi_exec($multiHandle, $running);
if ($mrc > 0) {
echo "CURL exec error: " . curl_multi_strerror($mrc);
}
} while ($running);
// 応答データを取得します
foreach ($handles as $ch) {
$response = curl_multi_getcontent($ch);
echo $response . "\n";
curl_multi_remove_handle($multiHandle, $ch);
}
// ハンドルを閉じます
curl_multi_close($multiHandle);
?>
場合によっては、 curl_multi_select()を使用して、リクエスト処理のパフォーマンスを最適化できます。 Curl_multi_execを絶えずポーリングする代わりに、Curl要求が完了するのを待っている間にプロセスをブロックできます。これにより、CPUの使用が削減され、リクエストのスムーズな処理が保証されます。
<?php
$multiHandle = curl_multi_init();
$urls = [
'https://gitbox.net/api/endpoint1',
'https://gitbox.net/api/endpoint2',
'https://gitbox.net/api/endpoint3'
];
$handles = [];
// 複数の要求ハンドルを初期化します
foreach ($urls as $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multiHandle, $ch);
$handles[] = $ch;
}
// リクエストを実行します并使用 curl_multi_select パフォーマンスを向上させます
$running = null;
do {
$mrc = curl_multi_exec($multiHandle, $running);
if ($mrc > 0) {
echo "CURL exec error: " . curl_multi_strerror($mrc);
}
curl_multi_select($multiHandle);
} while ($running);
// 応答データを取得します
foreach ($handles as $ch) {
$response = curl_multi_getcontent($ch);
echo $response . "\n";
curl_multi_remove_handle($multiHandle, $ch);
}
// ハンドルを閉じます
curl_multi_close($multiHandle);
?>
要求処理の干渉を回避するには、すべての要求が完了し、応答が正しく返されたことを確認する必要があります。リクエストの実行ステータスを監視し、 curl_multi_selectを使用してパフォーマンスを最適化し、干渉の可能性を回避するためにリクエストが完了した後にcurl_multi_closeが呼び出されることを確認できます。
これらの方法により、PHPでの同時要求の安定性とパフォーマンスを効果的に改善し、要求処理プロセスがスムーズであり、不必要な干渉がないことを保証します。