0

我目前有 PHP5.2。我最终想使用json_decode, 来解析通过 HTTP 请求获得的 JSON 文件的内容。

json_decode要求 JSON 在字符串中并作为参数传递,所以我通过file_get_contents.

把它想象成:

$JSON = file_get_contents($URL);

where$JSON是文件内容的存储字符串,$URL是通过 HTTP 请求获取文件的目标 URL。关于file_get_contentsPHP手册状态:

该函数返回读取的数据或失败时返回 FALSE。

就失败而言,我假设这FALSE会在超时(无法到达服务器$URL)、a 404(到达服务器,但文件不存在于$URL)、a 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_headerfile_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但不是 - 例如 - a 的特定情况下才有意义404


与现有答案类似,我还要说这$http_response_header是获取状态代码的好地方,从中可以很容易地捕获。

您还可以创建上下文以指定其他选项,file_get_contents例如,您也可以返回与false不同状态代码不同的返回值(例如 404)。

$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 类型的状态代码之外,您还可以从响应标头中获取它,解析完整数组的函数已在相关的 question/answer中进行了概述。

于 2012-10-01T15:03:39.557 回答