简体   繁体   English

如何解码/膨胀分块的 gzip 字符串?

[英]How to decode/inflate a chunked gzip string?

After making a gzip deflate request in PHP, I receive the deflated string in offset chunks, which looks like the following在 PHP 中发出 gzip deflate 请求后,我收到了偏移量块中的 deflated 字符串,如下所示

Example shortened greatly to show format:示例大大缩短以显示格式:

00001B4E
¾”kŒj…Øæ’ìÑ«F1ìÊ`+ƒQì¹UÜjùJƒZ\µy¡ÓUžGr‡J&=KLËÙÍ~=ÍkR
0000102F
ñÞœÞôΑüo[¾”+’Ñ8#à»0±R-4VÕ’n›êˆÍ.MCŽ…ÏÖr¿3M—èßñ°r¡\+
00000000

I'm unable to inflate that presumably because of the chunked format.大概是因为分块格式,我无法夸大它。 I can confirm the data is not corrupt after manually removing the offsets with a Hex editor and reading the gzip archive.在使用十六进制编辑器手动删除偏移量并读取 gzip 存档后,我可以确认数据没有损坏。 I'm wondering if there's a proper method to parse this chunked gzip deflated response into a readable string?我想知道是否有合适的方法将这个分块的 gzip 压缩响应解析为可读的字符串?

I might be able to split these offsets and join the data together in one string to call gzinflate, but it seems there must be an easier way.我也许能够拆分这些偏移量并将数据连接到一个字符串中以调用 gzinflate,但似乎必须有一种更简单的方法。

The proper method to deflate a chunked response is roughly as follows: 缩小响应的适当方法大致如下:

initialise string to hold result
for each chunk {
  check that the stated chunk length equals the string length of the chunk
  append the chunk data to the result variable
}

Here's a handy PHP function to do that for you ( FIXED ): 这是一个方便的PHP函数为你做( 固定 ):

function unchunk_string ($str) {

  // A string to hold the result
  $result = '';

  // Split input by CRLF
  $parts = explode("\r\n", $str);

  // These vars track the current chunk
  $chunkLen = 0;
  $thisChunk = '';

  // Loop the data
  while (($part = array_shift($parts)) !== NULL) {
    if ($chunkLen) {
      // Add the data to the string
      // Don't forget, the data might contain a literal CRLF
      $thisChunk .= $part."\r\n";
      if (strlen($thisChunk) == $chunkLen) {
        // Chunk is complete
        $result .= $thisChunk;
        $chunkLen = 0;
        $thisChunk = '';
      } else if (strlen($thisChunk) == $chunkLen + 2) {
        // Chunk is complete, remove trailing CRLF
        $result .= substr($thisChunk, 0, -2);
        $chunkLen = 0;
        $thisChunk = '';
      } else if (strlen($thisChunk) > $chunkLen) {
        // Data is malformed
        return FALSE;
      }
    } else {
      // If we are not in a chunk, get length of the new one
      if ($part === '') continue;
      if (!$chunkLen = hexdec($part)) break;
    }
  }

  // Return the decoded data of FALSE if it is incomplete
  return ($chunkLen) ? FALSE : $result;

}

The solution from user @user1309276 really helped me!用户@user1309276的解决方案真的帮助了我! Received from the server a gzip-compressed json response with transfer-encoding: chunked header.从服务器接收到带有transfer-encoding: chunked标头。 None of the solutions helped.没有一种解决方案有帮助。 This solution works like magic for me.这个解决方案对我来说就像魔术一样。 It just remove the first 10 bytes.它只是删除前 10 个字节。

$data = json_decode(gzinflate(substr($response->getContent(), 10)), true);

要解码String使用gzinflate ,Zend_Http_Client lib将有助于执行这种常见任务,使用它很简单,如果需要自己执行,请参考Zend_Http_Response代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM