Я использую функцию php file_get_contents() для выполнения HTTP-запроса. Чтобы сохранить пропускную способность, я решил добавить заголовок "Accept-Encoding: gzip" используя stream_context_create() .
Очевидно, file_get_contents() выводит строку с кодировкой gzip, поэтому я использую gzuncompress() для декодирования закодированной строки, но я получаю сообщение об ошибке с данными, переданными как аргумент.
[...] PHP Warning: gzuncompress(): data error in /path/to/phpscript.php on line 26
Я знаю, что есть еще одна функция, способная распаковывать gzipped-данные gzdecode() но она не включена в мою версию PHP (возможно, она доступна только в SVN).
Я знаю, что cUrl декодирует поток gzip на лету (без каких-либо проблем), но кто-то предложил мне использовать file_get_contents() вместо cUrl.
Вы знаете какой-либо другой способ распаковать gzip-данные на PHP или почему gzuncompress() выводит предупреждение? Абсурдно, что gzuncompress() работает не так, как ожидалось.
Примечания. Проблема, безусловно, связана с PHP: HTTP-запрос выполняется в Tumblr API, который дает хорошо закодированный ответ.
gzuncompress не будет работать для кодирования gzip . Это функция декомпрессии для архивов .Z .
В руководстве перечислены некоторые обходные пути для отсутствующего gzdecode() # 82930 или просто используйте один из upgradephp или временный файл временного файла gzopen.
Другой вариант – принудительное кодирование с gzinflate() с заголовком Accept-Encoding: а затем с помощью gzinflate() для декомпрессии.
Нашел это для меня: http://www.php.net/manual/en/function.gzdecode.php#106397
При желании попробуйте: http://digitalpbk.com/php/file_get_contents-garbled-gzip-encoding-website-scraping
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)); } }
Перед распаковкой данных вам необходимо собрать его. Поэтому, если заголовок содержит
Transfer-Encoding: chunked
вам нужно разблокировать его.
function http_unchunk($data) { $res=[]; $p=0; $n=strlen($data); while($p<$n) { if (preg_match("/^([0-9A-Fa-f]+)\r\n/",substr($data,$p,18),$m)) { $sz=hexdec($m[1]); $p+=strlen($m[0]); $res[]=substr($data,$p,$sz); $p+=$sz+2; } else { break; } } return implode('',$res); }
если Content-Encoding – это gzip или x-gzip или x-compress, используйте gzdecode, если Content-Encoding используется deflate, используйте gzdeflate
... if ($chunked) $body=http_unchunk($body); if ($gzip) $body=gzdecode($body); if ($deflate) $body=gzdeflate($body); ...