【问题标题】:Why PHP's gzuncompress() function can go wrong?为什么 PHP 的 gzuncompress() 函数会出错?
【发布时间】:2014-12-29 16:32:16
【问题描述】:

PHP 有自己的函数来处理 gzip 档案。我写了以下代码:

error_reporting(E_ALL);
$f = file_get_contents('http://spiderbites.nytimes.com/sitemaps/www.nytimes.com/sitemap.xml.gz');
echo $f;
$f = gzuncompress($f);
echo "<hr>";
echo $f;

First echo 通常输出带有正确标题的压缩文件(至少前两个字节是正确的)。如果我使用浏览器下载此文件,我可以轻松解压缩。

但是 gzuncompress 抛出了Warning: gzuncompress(): data error in /home/path/to/script.php on line 5

谁能指出我解决这个问题的正确方向?

编辑:

phpinfo() 输出部分

【问题讨论】:

  • 您可以使用 ob_gzhandler() 让 PHP 为您完成工作,因为如果未压缩的数据超过压缩输入数据长度的 32768 倍,函数 gzuncompress() 将返回错误,或者超过可选参数长度。或者您可以使用可选参数来定义长度。这应该很容易解决。
  • @unixmiah 在我的情况下,文件大小为 4169(压缩)/88406(未压缩),因此该比率远非 32768(实际比率约为 21)。
  • 您是否编辑了 php.ini 并启用了 zip 库?如果您还没有这样做,请在完成后重新启动您的网络服务器以进行您所做的更改。
  • @unixmiah 我包含了 phpinfo() 屏幕截图以明确这一点。正如我所看到的 - 一切都已启用。对吗?
  • @VladaKatlinskaya:看看马里奥的回答。

标签: php gzip unzip


【解决方案1】:

或者你可以使用正确的解压函数gzdecode()

【讨论】:

  • 经过测试:有效!非常感谢!你知道为什么gzuncompress() 函数会这样吗?
  • @VladaKatlinskaya "gzuncompress" 适用于所谓的 "zlib" 格式。而“gzdecode”解码 gzip 包装的数据。而“gzinflate”只是原始的 DEFLATE 算法数据。基本上每个gzdecode > gzuncompress > gzinflate 都会向流中添加更多元数据。
  • 值得注意的是,由于早期的 MSIE/IIS 错误,存在一些混淆,因为某些服务器发送的“zlib”流被错误地标记为“gzip”数据。因此,有时您必须使用 gzuncompress 和 gzdecode 进行探测。这就是为什么你可能更喜欢使用 PHPs curl 函数,它会自动处理这个问题。
  • 实际上这些错误导致原始 deflate 作为 zlib 流发送。没有错误标记的 gzip 流。
【解决方案2】:

请注意,gzuncompress() 可能无法解压缩某些压缩字符串并返回数据错误。

问题可能是外部压缩字符串在文件末尾有一个 CRC32 校验和,而不是像 PHP 预期的 Adler-32。

(http://php.net/manual/en/function.gzuncompress.php#79042)

这可能是它不起作用的一个选项。

用他的代码试试:

function gzuncompress_crc32($data) {
     $f = tempnam('/tmp', 'gz_fix');
     file_put_contents($f, "\x1f\x8b\x08\x00\x00\x00\x00\x00" . $data);
     return file_get_contents('compress.zlib://' . $f);
}

在此修改您的代码:

error_reporting(E_ALL);
$f = file_get_contents('http://spiderbites.nytimes.com/sitemaps/www.nytimes.com/sitemap.xml.gz');
echo $f;
$f = gzuncompress_crc32($f);
echo "<hr>";
echo $f;

据我在本地测试,它不再给出错误了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 2020-10-15
    • 1970-01-01
    • 2021-08-23
    相关资源
    最近更新 更多