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

时间:2016-07-12 05:15:05

标签: php compression zlib

当我通过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中不起作用吗?

任何想法都将不胜感激 - 谢谢!

1 个答案:

答案 0 :(得分:1)

问题是你的字符串太短而无法填充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头(78 9C =默认压缩)可以从头开始安全地写入,因为它的内容并不依赖于下一个字节。在这种情况下,不需要缓冲区。