web-dev-qa-db-ja.com

PHPでのCurlのタイムアウトの設定

私はphpを介してeXistデータベース上でカール要求を実行しています。データセットは非常に大きく、その結果、データベースはXML応答を返すために一貫して長い時間がかかります。これを修正するために、長いタイムアウトになるはずのカール要求を設定しました。

$ch = curl_init();
$headers["Content-Length"] = strlen($postString);
$headers["User-Agent"] = "Curl/1.0";

curl_setopt($ch, CURLOPT_URL, $requestUrl);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'admin:');
curl_setopt($ch,CURLOPT_TIMEOUT,1000);
$response = curl_exec($ch);
curl_close($ch);

ただし、curl要求は、要求が完了する前に一貫して終了します(ブラウザ経由で要求された場合は1000未満)。これがcurlでタイムアウトを設定するための適切な方法であるかどうか誰かが知っていますか?

199
Moki

ドキュメントを参照してください。 http://www.php.net/manual/en/function.curl-setopt.php

CURLOPT_CONNECTTIMEOUT - 接続しようとしている間待つ秒数。無期限に待機するには0を使用してください。
CURLOPT_TIMEOUT - cURL関数の実行を許可する最大秒数。

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); 
curl_setopt($ch, CURLOPT_TIMEOUT, 400); //timeout in seconds

phpスクリプトselfの実行時間を長くすることも忘れないでください。

set_time_limit(0);// to infinity for example
304
msangel

うーん、それは私にCURLOPT_TIMEOUTはすべてのcURL関数が実行するのに許される時間の長さを定義するように見えます。接続が完了するのを待つ最大時間をcURLに指示するので、実際には代わりにCURLOPT_CONNECTTIMEOUTを見るべきです。

53
Chad Birch

あなたのコードはタイムアウトを1000 に設定します。ミリ秒の間、CURLOPT_TIMEOUT_MSを使用してください。

26
Matt Humphreys

これには、一部の人々にとって意味があるかもしれないという奇妙なことがあります... PHP docsコメントから。

CURLのタイムアウトを1秒未満にしたい場合は、CURLOPT_TIMEOUT_MSを使用できます。ただし、 "Unix系システム"には、エラーが発生して<1000 msの場合にlibcurlが直ちにタイムアウトするバグ/ "機能"があります。 "cURLエラー(28):タイムアウトに達しました。"この動作の説明は次のとおりです。

「libcurlが標準のシステム名リゾルバを使用するように構築されている場合でも、転送のその部分ではタイムアウトのために1秒の許容最小タイムアウトでフル秒の解決が使用されます。」

これがPHP開発者にとって意味することは、 "libcurlが標準のシステム名リゾルバを使用しているかどうかわからないので、最初にテストせずにこの関数を使用することはできません。 )」

問題は、(Li | U)nixでは、libcurlが標準の名前リゾルバを使用するとき、libcurlがタイムアウトアラームであると考える名前解決中にSIGALRMが発生します。

解決策は、CURLOPT_NOSIGNALを使用してシグナルを無効にすることです。これは、タイムアウトをテストできるように10秒の遅延を発生させるように要求するスクリプトの例です。

if (!isset($_GET['foo'])) {
    // Client
    $ch = curl_init('http://localhost/test/test_timeout.php?foo=bar');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200);
    $data = curl_exec($ch);
    $curl_errno = curl_errno($ch);
    $curl_error = curl_error($ch);
    curl_close($ch);

    if ($curl_errno > 0) {
        echo "cURL Error ($curl_errno): $curl_error\n";
    } else {
        echo "Data received: $data\n";
    }
} else {
    // Server
    sleep(10);
    echo "Done.";
}

http://www.php.net/manual/ja/function.curl-setopt.php#104597から

24
Simon East

あなたはあなたとファイルの間のタイムアウトについて確かめる必要があるでしょう。この場合はPHPとCurlです。

転送がまだアクティブなときにCurlがタイムアウトしないようにするには、CURLOPT_TIMEOUTではなく01000に設定する必要があります。

curl_setopt($ch, CURLOPT_TIMEOUT, 0);

PHPでは、制限時間を削除しなければ、PHP自分で(デフォルトで30秒後に)Curlの要求に沿ってスクリプトを強制終了します。 これだけで問題は解決します
さらに、データの整合性が必要な場合は、ignore_user_abortを使用してセキュリティ層を追加できます。

# The maximum execution time, in seconds. If set to zero, no time limit is imposed.
set_time_limit(0);

# Make sure to keep alive the script when a client disconnect.
ignore_user_abort(true);

クライアントの接続が切断されると、スクリプトの実行が中断され、データが破損する可能性があります。
例えば。あなたの場合は部分的なファイルをダウンロードするでしょうが、あなたはこれについて気にするかもしれませんし、そうでないかもしれません。

このスレッドがエンジンのトップにいるのでこの古い質問に答えるとCURL_TIMEOUTが検索されます。

9
MarcoP

ブラウザから要求を実行することはできません。それはCURL要求を実行しているサーバーが応答するのを待つ間にタイムアウトします。ブラウザは、おそらくデフォルトのネットワークタイムアウトである1〜2分でタイムアウトします。

あなたはコマンドライン/端末からそれを実行する必要があります。

8
Brent Baisley

FastCGIアプリケーションとしてPHPを使用している場合は、fastCGIタイムアウト設定を確認してください。参照してください。 PHP curl put 500 error

3
wbinky