PHPのCurl拡張機能を使用する場合、 curl_multi_*シリーズ関数は複数のHTTP要求を同時に実行できます。 curl_multi_exec()を介してバッチでリクエストを送信し、 curl_multi_close()を使用してハンドルを閉じます。これらの関数は強力ですが、 curl_setopt()と組み合わせて使用すると、いくつかの落とし穴になりやすいです。以下に、いくつかの一般的な間違いとそれらを避ける方法について説明します。
curl_multi_exec()を使用して複数のリクエストを処理するためにバッチを使用する場合、各リクエストの個々のオプションを設定する必要があります。複数のハンドルを追加するときにcurl_setopt()が正しく設定されていない場合、リクエストが失敗したり、誤った結果を返すことがあります。
$ch1 = curl_init();
$ch2 = curl_init();
curl_setopt($ch1, CURLOPT_URL, 'https://gitbox.net/api/data1');
curl_setopt($ch2, CURLOPT_URL, 'https://gitbox.net/api/data2');
// 他の必要なオプションを設定するのを忘れました,のように CURLOPT_RETURNTRANSFER
各カールハンドルに必要なオプションを設定してください。例えば:
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_multi_close()およびcurl_close()は両方ともCurlハンドルを閉じるために使用されますが、アクションの範囲は異なります。 curl_close()は1つのCurlハンドルのみを閉じますが、 Curl_multi_close()は複数のCurl要求ですべてのハンドルを閉じます。これらの2つの機能を誤って使用すると、リソースが正しくリリースされない場合があります。そうしないと、プログラムはその後のリクエストで例外があります。
curl_multi_close($multiHandle); // 間違い,なぜなら $multiHandle 複数のハンドルを閉じる必要があります
複数の要求を使用する場合、 curl_multi_close()を使用して、各ハンドルを完了して処理した後、複数のハンドルを閉じます。
// 複数のリクエストを実行します
curl_multi_exec($multiHandle, $running);
// 各個人を閉じます cURL ハンドル
curl_close($ch1);
curl_close($ch2);
// 正しく使用してください curl_multi_close()
curl_multi_close($multiHandle);
開発者がcurl_multi_exec()を使用して複数のリクエストを送信すると、リクエストが正しく完了するのを待たないため、接続を時期尚早に閉じることがあります。 curl_multi_exec()は非同期に実行されるため、すべてのリクエストが完了したことを確認してから、 curl_multi_close()を呼び出す必要があります。
// 没有等待请求完成就关闭ハンドル
curl_multi_close($multiHandle);
$実行パラメーターを検出することにより、接続を閉じる前にすべてのリクエストが完了することを確認してください。
$running = null;
do {
curl_multi_exec($multiHandle, $running);
} while ($running > 0);
curl_multi_close($multiHandle);
場合によっては、開発者は同じカールハンドルを再利用しようとする場合があります。これは、リクエストエラーやパフォーマンスの問題に簡単につながる可能性があります。新しいリクエストが送信されるたびに、新しいカールハンドルを作成し、さまざまなオプションを設定する必要があります。
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gitbox.net/api/data1');
// 复用相同的ハンドル
curl_setopt($ch, CURLOPT_URL, 'https://gitbox.net/api/data2'); // 間違い,应该创建新的ハンドル
リクエストごとに新しいカールハンドルを作成してください。
$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_URL, 'https://gitbox.net/api/data1');
$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_URL, 'https://gitbox.net/api/data2');
curl_multi_exec()がリクエストを実行すると、さまざまなネットワークまたはサーバーエラーが発生する可能性があります。これらのエラーを正しく処理できるようにするには、 curl_error()およびcurl_errno()をエラーデバッグに使用する必要があります。
curl_multi_exec($multiHandle, $running); // リクエストを実行します,但没有处理間違い
各リクエストが完了したら、エラーメッセージを確認して出力します。
// リクエストを実行します
curl_multi_exec($multiHandle, $running);
// 間違い处理
foreach ($handles as $ch) {
if ($errno = curl_errno($ch)) {
echo "cURL error: " . curl_error($ch);
}
}