2013-12-14 105 views
2

我最近想從Web服務中獲取並解碼API響應。我認爲只是file_get_contents,然後json_decode生成的字符串應該工作。無法從file_get_contents json_decode字符串

它看起來像我必須處理gzipped響應和格式不正確的JSON來最終解碼字符串。我如何處理這些?

回答

2

最近我想從Web服務中獲取並解碼API響應,然後發現它不僅僅是file_get_contentsjson_decode這個字符串。我必須處理gzip響應和格式錯誤的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); 
    } 
} 
+1

沒關係提出和回答你自己的問題,其實我們很喜歡它 - 雖然我們要求你分割他們作爲完整的,個別的問題和答案。我已經採取了您的問題的「答案」部分,並將其移至此處。 – Flexo

+1

對不起,我以前的自我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); 


    } 
+0

謝謝,馬克斯。你的cURL真的很有用。我已經Google和谷歌我的問題幾個小時終於寫上述我的功能。我已經讀了幾十個stackoverflow的答案,但他們都沒有工作。我之前嘗試過cURL,但根本沒有工作,因爲響應仍然返回gzip內容。 也許curl_setopt($ ch,CURLOPT_ENCODING,'');在一行中解決所有問題的選項。我以前沒有使用過。 –

+0

@MurdaniEko,你可以用CURLOPT_ENCODING放任何你想要的編碼,或者你可以像在代碼中一樣發送它,並獲得沒有任何編碼的頁面,順便說一句,你可以通過點擊勾來接受我的答案 – max