2013-12-14 6 views
2

Недавно я хотел получить и декодировать ответ API от веб-службы. Я думал, что просто file_get_contents, а затем json_decode результирующая строка должна работать.Не удалось создать строку json_decode из file_get_contents

Похоже, мне приходится иметь дело с gzipped-ответом и искаженным JSON, чтобы окончательно декодировать строку. Как я могу справиться с этим?

ответ

2

Недавно я хотел получить и декодировать ответ API от веб-службы, а затем выяснил, что это было намного больше, чем просто file_get_contents и json_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

Извините за мой предыдущий формат самообслуживания. В следующий раз я сделаю это лучше. Спасибо, что редактировали мой пост. Я очень ценю это –

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 действительно работает. У меня есть Googled и Binged моя проблема часами, чтобы наконец написать мою функцию выше. Я прочитал десятки ответов stackoverflow, но ни один из них не работает. Раньше я пытался использовать cURL, но не работал вообще, так как ответ все еще возвращал gzipped-контент. Возможно, curl_setopt ($ ch, CURLOPT_ENCODING, ''); варианты, которые решают все в одной строке. Я не использовал это раньше. –

+0

@MurdaniEko точно, вы можете поместить любую кодировку, которую хотите с помощью CURLOPT_ENCODING, или можете отправить ее пустым, как в коде, и получить страницу без какой-либо кодировки, кстати, вы можете принять мой ответ, нажав на галочку – max

Смежные вопросы