4

file_get_contents 経由で信頼できない API に接続しています。信頼性が低いため、次のように API 呼び出しを while ループに入れることにしました。

$resultJSON = FALSE;

while(!$resultJSON) {
    $resultJSON = file_get_contents($apiURL);
    set_time_limit(10);
}

別の言い方をすれば、3 回目の試行で成功する前に、API が 2 回失敗したとします。3 つのリクエストを送信しましたか、それとも 3 秒のウィンドウに収まる数百のリクエストを送信しましたか?

4

4 に答える 4

8

file_get_contents()、基本的にPHPのすべての関数と同様に、ブロッキング呼び出しです。

于 2012-11-16T18:34:02.383 に答える
2

はい、ブロッキング機能です。また、値が具体的に「false」であるかどうかを確認する必要があります。(==ではなく===が使用されることに注意してください。)最後に、10秒間スリープします。set_time_limit()は、自動的に強制終了されるまでの最大実行時間を設定するために使用されます。

set_time_limit(300); //Run for up to 5 minutes.

$resultJSON = false;
while($resultJSON === false)
{
    $resultJSON = file_get_contents($apiURL);
    sleep(10);
}
于 2012-11-16T18:34:42.957 に答える
1

「ブロック」しないPHPの関数を知りません。別の方法として、サーバーがそのようなことを許可している場合は、次のことができます。

  1. pcntl_fork()API 呼び出しが完了するのを待っている間に、スクリプトで他のことを使用および実行します。
  2. を使用exec()してバックグラウンドで別のスクリプトを呼び出し [を使用して&] が使用できない場合に API 呼び出しを行いますpcntl_fork()

ただし、その API の呼び出しが成功しない限り、スクリプト内で文字通り何もできない場合は、呼び出しが「ブロック」されるかどうかは問題ではありません。本当に心配すべきことは、この API の待機に非常に多くの時間を費やしているため、設定された時間を超えてmax_execution_time、スクリプトが適切に完了せずに途中で中止されることです。

$max_calls = 5;
for( $i=1; $i<=$max_calls; $i++ ) {
    $resultJSON = file_get_contents($apiURL);
    if( $resultJSON !== false ) {
        break;
    } else if( $i = $max_calls ) {
        throw new Exception("Could not reach API within $max_calls requests.");
    }
    usleep(250000); //wait 250ms between attempts
}

file_get_contents() デフォルトのタイムアウトが60 秒であるため、スクリプトが強制終了される危険性があることに注意してください。はるかに妥当なタイムアウト値を設定できるため、代わりに cURL を使用することを真剣に検討してください。

于 2012-11-16T19:10:38.090 に答える
1

@Sammitch の提案を拡張して、代わりに cURL を使用しますfile_get_contents()

<?php
$apiURL = 'http://stackoverflow.com/';

$curlh = curl_init($apiURL);
// Use === not ==
// if ($curlh === FALSE) handle error;
curl_setopt($curlh, CURLOPT_FOLLOWLOCATION, TRUE); // maybe, up to you
curl_setopt($curlh, CURLOPT_HEADER, FALSE); // or TRUE, according to your needs
curl_setopt($curlh, CURLOPT_RETURNTRANSFER, TRUE);
// set your timeout in seconds here
curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curlh, CURLOPT_TIMEOUT, 30);
$resultJSON = curl_exec($curlh);
curl_close($curlh);
// if ($resultJSON === FALSE) handle error;
echo "$resultJSON\n"; // Now process $resultJSON
?>

さらに多くのcurl_setoptオプションがあります。それらをチェックする必要があります。

もちろん、これはcURL が利用可能であることを前提としています。

于 2012-11-16T19:06:57.397 に答える