【问题标题】:Dealing with errors in Fetching JSON files to decode处理 Fetching JSON files to decode 中的错误
【发布时间】:2012-10-01 14:26:47
【问题描述】:

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

json_decode 要求 JSON 在字符串中并作为参数传递,因此我通过file_get_contents 将文件读入字符串。

把它想象成:

$JSON = file_get_contents($URL);

其中$JSON 是文件内容的存储字符串,$URL 是通过HTTP 请求获取文件的目标URL。关于file_get_contents PHP 手册指出:

函数返回读取的数据,失败则返回FALSE。

就失败而言,我假设这会在超时(无法到达$URL 的服务器)、404(到达服务器,但文件在$URL 不存在)时返回FALSE )、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 中使用它们。有什么方法可以更好地处理这类事情吗?

【问题讨论】:

    标签: php json httprequest


    【解决方案1】:

    在对 URL 的 file_get_contents() 调用之后,PHP 会创建一个名为 $http_response_header 的变量,您应该可以使用它来满足您的需求。

    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 次。

    【讨论】:

    • 我在想read_data 应该有json 在那里(用于递归)。 $http_response_header 的概念正是我所需要的!我在file_get_contents 的手册页上没有看到明显的内容。这正是我所需要的,谢谢!
    【解决方案2】:

    我想说一个更好的方法是在重试之前实际考虑 HTTP 状态代码。

    重试仅在您获得503 而不是 - 例如 - 404 的特定情况下才有意义。


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

    您还可以创建上下文以指定其他选项,例如,您可以让 file_get_contents 在不同的状态代码(例如 404)上返回与 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 的状态代码之外,您还可以从响应标头中获取它,a related question/answer 中概述了一个解析完整数组的函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-31
      • 1970-01-01
      • 1970-01-01
      • 2012-12-13
      相关资源
      最近更新 更多