【问题标题】:Failed to json_decode string from file_get_contents无法从 file_get_contents json_decode 字符串
【发布时间】:2014-01-02 07:03:24
【问题描述】:

我最近想从 Web 服务获取和解码 API 响应。我认为只是 file_get_contents 然后 json_decode 生成的字符串应该可以工作。

看来我必须处理压缩响应和格式错误的 JSON 才能最终解码字符串。我该如何处理这些?

【问题讨论】:

    标签: php file-get-contents json


    【解决方案1】:

    最近我想从 Web 服务获取和解码 API 响应,然后发现它不仅仅是 file_get_contentsjson_decode 字符串。我必须处理压缩响应和格式错误的 JSON 才能最终解码字符串。

    经过数小时的搜索,下面的两个功能刚刚拯救了我的一天。

    // http://stackoverflow.com/questions/8895852/uncompress-gzip-compressed-http-response
    if ( ! function_exists('gzdecode')) {
    /**
     * Decode gz coded data
     * 
     * http://php.net/manual/en/function.gzdecode.php
     * 
     * Alternative: http://digitalpbk.com/php/file_get_contents-garbled-gzip-encoding-website-scraping
     * 
     * @param string $data gzencoded data
     * @return string inflated data
     */
    function gzdecode($data)     {
        // strip header and footer and inflate
    
        return gzinflate(substr($data, 10, -8));
    }
    }
    
    
    /**
     * Fetch the requested URL and return it as decoded json object
     * 
     * @author string  Murdani Eko
     * @param  string  $url
     */
    function get_json_decode( $url ) {
    
      $response = file_get_contents( $url );
      $response = trim( $response );
    
      // is it a valid json string?
      $jsondecoded = json_decode( $response );
      if( json_last_error() == JSON_ERROR_NONE ) {
        return $jsondecoded;
      }
    
      // yay..! it's a gzencoded string
      if( json_last_error() == JSON_ERROR_UTF8 ) {
        $response = gzdecode($response);
    
        /* After gzdecoded, there is a chance that the response 
         * will have extra character after the curly brackets e.g. }}gi or }} ee
         * This will cause malformed JSON, and later failed json decoding
         */
    
        // we search-reverse the closing curly bracket position
        $last_curly_pos = strrpos($response, '}');
        $last_curly_pos++; 
    
        // extract the correct json format using the last curly bracket position
        $good_response = substr($response, 0, $last_curly_pos);
    
        return json_decode( $good_response );
      }
    }
    

    【讨论】:

    • 可以提出并回答您自己的问题,事实上我们非常喜欢它——尽管我们要求您将它们拆分为完整的、单独的问题和答案。我已将您问题的“答案”部分移至此处。
    • 抱歉我之前的自我 QA 格式。下次我会做得更好。感谢您花时间编辑我的帖子。我真的很感激
    【解决方案2】:

    您可以使用curl 代替file_get_contents 并且无需任何编码即可获取页面内容

       function get_url($link){
    
          $ch = curl_init();
          curl_setopt($ch, CURLOPT_HEADER, 0);
          curl_setopt($ch, CURLOPT_VERBOSE, 0);
          curl_setopt($ch,CURLOPT_ENCODING, '');
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($ch, CURLOPT_URL, ($link));
          $response = curl_exec($ch);
          curl_close($ch);
          return ($response); 
    
    
        }
    

    【讨论】:

    • 谢谢,马克斯。你的 cURL 真的很有效。我已经用谷歌搜索并搜索了几个小时的问题,最终在上面编写了我的函数。我已经阅读了数十个 stackoverflow 答案,但没有一个有效。我之前尝试过 cURL,但根本没有工作,因为响应仍然返回 gzip 压缩的内容。也许 curl_setopt($ch,CURLOPT_ENCODING, '');在一行中解决所有问题的选项。我以前没用过。
    • @MurdaniEko 确切地说,您可以使用 CURLOPT_ENCODING 输入您想要的任何编码,或者您可以像在代码中一样将其发送为空并获取没有任何编码的页面,顺便说一句,您可以通过单击勾选来接受我的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多