php 压缩过滤器和 gzcompress 没有返回相同的结果

php compression filters and gzcompress not returning the same result

当我通过 zlib 运行 我的代码时得到不同的输出 compression filters

我的代码:

<?php
$data = 'zzzzzzzzzzzzzzzzzzzzzzzzzzz';

$params = array('level' => 6, 'window' => 15, 'memory' => 9);
//$params = 6;
$fp = fopen('php://memory', 'wb+');
stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_WRITE, $params);
fputs($fp, $data);
rewind($fp);

echo bin2hex(stream_get_contents($fp)) . "\n";
echo bin2hex(gzcompress($data)) . "\n";

输出:

789c
789cabaaa2260000bce3252d

我的理解是 789c 是 header for normal compression。所以我不知道发生了什么。压缩流在 PHP 中不起作用吗?

如有任何想法,我们将不胜感激 - 谢谢!

问题是您的字符串太短,无法填满 DEFLATE 工作缓冲区。而且因为您的流没有明确关闭,所以它根本不会被处理,也不会被刷新。当调用 stream_get_contents() 时,您的数据仍在缓冲区中。

如果我们通过注入足够大的随机字节块来强制刷新缓冲区,一些数据实际上会写入流中:

$data = openssl_random_pseudo_bytes(65536);

$params = array('level' => 6, 'window' => 15, 'memory' => 9);
$fp = fopen('php://memory', 'wb+');
stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_WRITE, $params);
fputs($fp, $data);
rewind($fp);

echo substr(bin2hex(stream_get_contents($fp)), 0, 32) . "\n";
echo substr(bin2hex(gzcompress($data)), 0, 32) . "\n";

示例输出(仅显示前 16 个字节):

789c000b80f47f453c070e41c557acdb
789c000b80f47f453c070e41c557acdb

另一方面,ZLIB header(78 9C = 默认压缩)可以安全地从头开始写入,因为它的内容不依赖于下一个字节。在这种情况下不需要缓冲区。