0

私は現在PHP5.2を持っています。json_decode最終的には、HTTPリクエストを介して取得したJSONファイルの内容を解析するためにを使用したいと思います。

json_decodeJSONが文字列に含まれ、パラメーターとして渡される必要があるため、を介してファイルを文字列に読み込んでいますfile_get_contents

それを次のように考えてください:

$JSON = file_get_contents($URL);

ここ$JSONで、はファイルの内容のストレージ文字列であり、$URLはHTTPリクエストを介してファイルをフェッチするためのターゲットURLです。file_get_contentsPHPマニュアルの状態について:

この関数は、読み取ったデータを返すか、失敗した場合はFALSEを返します。

失敗する限り、これはFALSEタイムアウト(サーバーに到達できなかった$URL)、404(サーバーに到達したが、ファイルはに存在しなかった$URL)、503(サーバーに到達したが、ビジー状態で適切に応答できなかった)のいずれかで返されると想定しています。 、または500(内部サーバーエラー、通常は発生しないはずです)。

とにかく、私が最も懸念している上記のエラーのうち、503私がヒットしているサーバーは、HTTPリクエストでこれをスローすることがあります。このような場合は、もう一度やり直したいと思います。

だから私はこれを思いついた:

$JSON = null; //Initially set to null as we have not fetched it

for($attempt = 0; $attempt < 3; $attempt++) //Try 3 times to fetch it
    if($JSON = file_get_contents($URL)) break; //If we fetch it, stop trying to

//Kill the script if we couldn't fetch it within 3 tries
if($JSON == null) die("Could not get JSON file"); 

この種の仕事はしますが、私はそれがあまりしっかりしていないと思います。私はコンテキストについてもっと読んでいましたが、PHPでそれらを使用する方法を完全にはフォローしていません。この種のことをもっとうまく処理できる方法はありますか?

4

2 に答える 2

2

PHPは、URL$http_response_headerの呼び出し後に呼び出される変数を作成file_get_contents()します。これは、好みに応じて使用できるはずです。

function read_json_data($url, $attempts = 0) {

    $json = file_get_contents($url);

    if (!$json && isset($http_response_header) && strstr($http_response_header[0], '503') && $attempts++ <= 2) {

        return read_json_data($url, $attempts);

    }

    if (!$json) {

        throw new Exception("Maximum attempts or not a 503 status code.");

    }

    return json_decode($json);

}

使用法:

$json = read_json_data($url);

503を打つと最大3回実行されます。

于 2012-10-01T14:41:14.317 に答える
1

はるかに良い方法は、再試行する前に実際にHTTPステータスコードを考慮に入れることだと思います。

再試行は、取得した特定の場合にのみ意味がありますが、503たとえば、aは取得しません404


既存の回答と同様に$http_response_header、ステータスコードを取得するのに適した場所であり、そこからキャプチャするのはかなり簡単です。

また、コンテキストを作成して追加のオプションを指定することもできます。たとえば、さまざまなステータスコード(404など)file_get_contentsとは異なるリターンを返すこともできます。false

$context = stream_context_create(['http' => ['ignore_errors' => 1]]);

$data = file_get_contents($url, null, $context);

$code = null;

$http_response_header 
    && sscanf($http_response_header[0], 'HTTP/%*d.%*d %d', $code)
;

返されるmime-typeを確認したいステータスコードとは別に、応答ヘッダーからそれをフェッチすることもできます。完全な配列を解析する関数は、関連する質問/回答で概説されています。

于 2012-10-01T15:03:39.557 に答える