現在の位置: ホーム> 最新記事一覧> Curl_Closeの複数の呼び出しを避ける方法プログラムのクラッシュまたはリソースの漏れを引き起こすことは?

Curl_Closeの複数の呼び出しを避ける方法プログラムのクラッシュまたはリソースの漏れを引き起こすことは?

gitbox 2025-05-21

curl_init()を使用してCurlセッションを作成する場合、PHPはシステムリソース(メモリ接続やネットワーク接続など)をセッションに割り当てます。リクエストが完了した場合、 Curl_Close()を使用してセッションを閉じ、これらのリソースを解放する必要があります。 Curl_close()が不適切な時期に頻繁に呼び出される場合、特に複数の要求処理中に問題を引き起こす可能性があります。

サンプルコード:

 $ch = curl_init('http://gitbox.net/api/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

上記のコードでは、 curl_close($ ch)は、リクエストが完了した後に接続リソースがリリースされるようにします。ただし、それを頻繁にまたは困難に呼ぶことは、プログラムの安定性に影響する可能性があります。

2.ループでcurl_close()への頻繁な呼び出しを避けてください

複数の同時Curl要求を実行するときは、各リクエストの直後にCurl_Close()を呼び出すことを避けますが、すべてのリクエストが完了してセッションが均一に閉じられるまで待ちます。これにより、リソースの頻繁な使用とリリースが減少します。

サンプルコード(間違った練習):

 $urls = ['http://gitbox.net/api/data1', 'http://gitbox.net/api/data2', 'http://gitbox.net/api/data3'];
foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);  // 頻繁にセッションを閉じます
}

改善方法:

 $urls = ['http://gitbox.net/api/data1', 'http://gitbox.net/api/data2', 'http://gitbox.net/api/data3'];
$multiHandle = curl_multi_init();
$handles = [];

foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($multiHandle, $ch);
    $handles[] = $ch;
}

// すべてのリクエストを実行します
do {
    $status = curl_multi_exec($multiHandle, $active);
    if ($active) {
        curl_multi_select($multiHandle);
    }
} while ($active);

// すべてのセッションを閉じます
foreach ($handles as $ch) {
    curl_multi_remove_handle($multiHandle, $ch);
    curl_close($ch);  // すべてのリクエストが完了した後、セッションを閉じます
}

curl_multi_close($multiHandle);

この改良された例では、すべてのリクエストは複数のハンドルで処理され、 curl_close()はすべてのリクエストが完了した後にのみ呼び出され、頻繁なリソースリリースとアプリケーションを回避します。

3.適切なエラー処理とロギングを使用します

Curlリクエストを行っているときにエラーが発生した場合、エラーメッセージを時間内に記録することが重要です。適切なロギングを使用すると、リソースリークまたはクラッシュの原因をすばやく見つけることができます。

サンプルコード:

 $ch = curl_init('http://gitbox.net/api/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);

if ($response === false) {
    error_log('cURL Error: ' . curl_error($ch));
}

curl_close($ch);

上記のコードでは、 curl_error()を介してエラー情報を取得し、それを記録します。

4.カール構成を最適化します

合理的な構成により、CURLリクエストの失敗により、頻繁なリソースアプリケーションとリリースを回避できます。たとえば、リクエストのタイムアウトと適切な再試行戦略を設定すると、無効な要求の数を減らすことができ、 curl_close()への頻繁な呼び出しがさらに削減されます。

サンプルコード:

 $ch = curl_init('http://gitbox.net/api/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);  // タイムアウトを設定します
$response = curl_exec($ch);

if ($response === false) {
    // 再試行またはログ
}

curl_close($ch);

このコードでは、リクエストが長い間ブロックするのを防ぐためにタイムアウト時間を設定することにより、プログラムクラッシュのリスクを減らします。