gzinflate

(PHP 4 >= 4.0.4, PHP 5, PHP 7, PHP 8)

gzinflate解压缩一个压缩字符串

描述

gzinflate(string $data, int $max_length = 0): string|false

此函数解压缩一个压缩字符串。

参数

data

gzdeflate() 压缩的数据。

max_length

解码数据的最大长度。

返回值

原始未压缩数据,或发生错误时为 false

如果未压缩数据超过压缩输入 data 长度的 32768 倍,或者除非 max_length0,超过可选参数 max_length,该函数将返回错误。

示例

示例 #1 gzinflate() 示例

<?php
$compressed
= gzdeflate('Compress me', 9);
$uncompressed = gzinflate($compressed);
echo
$uncompressed;
?>

参见

添加注释

用户贡献注释 10 个注释

35
dekho-ji.com 上的匿名用户
11 年前
要在 PHP 代码中解码/解压缩接收到的 HTTP POST 数据,请请求通过 HTTP POST GZIP/DEFLATE 压缩格式从 Java/Android 应用程序发送过来的数据

1) 从 Java Android 应用程序使用 DeflaterOutputStream java 类发送到 PHP 的数据,并在 PHP 中接收如下所示
echo gzinflate( substr($HTTP_RAW_POST_DATA,2,-4) ) . PHP_EOL . PHP_EOL;

2) 从 Java Android 应用程序使用 GZIPOutputStream java 类发送到 PHP 的数据,并在 PHP 代码中接收如下所示
echo gzinflate( substr($HTTP_RAW_POST_DATA,10,-8) ) . PHP_EOL . PHP_EOL;

从 Java Android 端(API 级别 10+)开始,以 DEFLATE 压缩格式发送数据
String body = "Lorem ipsum shizzle ma nizle";
URL url = new URL("http://www.url.com/postthisdata.php");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Content-encoding", "deflate");
conn.setRequestProperty("Content-type", "application/octet-stream");
DeflaterOutputStream dos = new DeflaterOutputStream(
conn.getOutputStream());
dos.write(body.getBytes());
dos.flush();
dos.close();
BufferedReader in = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String decodedString = "";
while ((decodedString = in.readLine()) != null) {
Log.e("dump",decodedString);
}
in.close();

在 PHP 端(v 5.3.1)上,用于解压缩此 DEFLATE 数据的代码将是
echo substr($HTTP_RAW_POST_DATA,2,-4);

从 Java Android 端(API 级别 10+)开始,以 GZIP 压缩格式发送数据

String body1 = "Lorem ipsum shizzle ma nizle";
URL url1 = new URL("http://www.url.com/postthisdata.php");
URLConnection conn1 = url1.openConnection();
conn1.setDoOutput(true);
conn1.setRequestProperty("Content-encoding", "gzip");
conn1.setRequestProperty("Content-type", "application/octet-stream");
GZIPOutputStream dos1 = new GZIPOutputStream(conn1.getOutputStream());
dos1.write(body1.getBytes());
dos1.flush();
dos1.close();
BufferedReader in1 = new BufferedReader(new InputStreamReader(
conn1.getInputStream()));
String decodedString1 = "";
while ((decodedString1 = in1.readLine()) != null) {
Log.e("dump",decodedString1);
}
in1.close();

在 PHP 端(v 5.3.1)上,用于解压缩此 GZIP 数据的代码将是
echo substr($HTTP_RAW_POST_DATA,10,-8);

使用所有可用格式打印压缩数据的有用 PHP 代码。

$data = "Lorem ipsum shizzle ma nizle";
echo "\n\n\n";
for($i=-1;$i<=9;$i++)
echo chunk_split(strtoupper(bin2hex(gzcompress($data,$i))),2," ") . PHP_EOL . PHP_EOL;
echo "\n\n\n";
for($i=-1;$i<=9;$i++)
echo chunk_split(strtoupper(bin2hex(gzdeflate($data,$i))),2," ") . PHP_EOL . PHP_EOL;
echo "\n\n\n";
for($i=-1;$i<=9;$i++)
echo chunk_split(strtoupper(bin2hex(gzencode($data,$i,FORCE_GZIP))),2," ") . PHP_EOL . PHP_EOL;
echo "\n\n\n";
for($i=-1;$i<=9;$i++)
echo chunk_split(strtoupper(bin2hex(gzencode($data,$i,FORCE_DEFLATE))),2," ") . PHP_EOL . PHP_EOL;
echo "\n\n\n";

希望这有帮助。如果您省了很多精力和时间,请点赞。
5
inka.de 上的 felix.klee
11 年前
下面的代码说明了第二个参数的使用,尤其是为了防止致命内存溢出错误。它输出

1000000
1000000
错误

在 32 位 Linux 上使用 PHP 5.3 测试。

<?php

function tryToGzinflate($deflatedData, $maxLen = 0) {
$data = gzinflate($deflatedData, $maxLen);
if (
$data === false)
echo
'error<br>';
else
echo
strlen($data).'<br>';
}

// 随机数据:
$data = '';
for (
$i = 0; $i < 1000000; $i++)
$data .= chr(mt_rand(97, 122)); // a-z

$deflatedData = gzdeflate($data);

ini_set('memory_limit', '5M'); // 足够的内存
tryToGzinflate($deflatedData);
tryToGzinflate($deflatedData, strlen($data));

ini_set('memory_limit', '100'); // 少量内存
tryToGzinflate($deflatedData, 100);
tryToGzinflate($deflatedData); // 导致致命内存溢出错误
?>
8
ua.fm 上的 vitall
14 年前
适用于 gzip 和分块数据,尤其是当您收到 "Content-Encoding: gzip" 和 "Transfer-Encoding: chunked" 头部时,正确的函数

<?php
function decode_gzip($h,$d,$rn="\r\n"){
if (isset(
$h['Transfer-Encoding'])){
$lrn = strlen($rn);
$str = '';
$ofs=0;
do{
$p = strpos($d,$rn,$ofs);
$len = hexdec(substr($d,$ofs,$p-$ofs));
$str .= substr($d,$p+$lrn,$len);
$ofs = $p+$lrn*2+$len;
}while (
$d[$ofs]!=='0');
$d=$str;
}
if (isset(
$h['Content-Encoding'])) $d = gzinflate(substr($d,10));
return
$d;
}
?>

尽情享受!
7
Steven Lustig
13 年前
您可以使用此方法从 Linux 命令行 gzip 解压缩字符串,方法是删除前 10 个字节

<?php
$inflatedOutput
= gzinflate(substr($output, 10, -8));
?>
4
boris at gamate dot com
21 年前
检索 mod_gzip 压缩的内容时,使用 gzinflate() 解码数据,请确保从检索到的内容中删除前 10 个字符。

<?php $dec = gzinflate(substr($enc,10)); ?>
5
patatraboum at free dot fr
16 年前
某些 gz 字符串会去除标题并返回解压缩后的内容
它实际上处理了 gz 的第一个成员
有关更多详细信息和 gzdecode 的改进,请参阅 rfc1952,网址为:http://www.faqs.org/rfcs/rfc1952.html

<?php
function gzBody($gzData){
if(
substr($gzData,0,3)=="\x1f\x8b\x08"){
$i=10;
$flg=ord(substr($gzData,3,1));
if(
$flg>0){
if(
$flg&4){
list(
$xlen)=unpack('v',substr($gzData,$i,2));
$i=$i+2+$xlen;
}
if(
$flg&8) $i=strpos($gzData,"\0",$i)+1;
if(
$flg&16) $i=strpos($gzData,"\0",$i)+1;
if(
$flg&2) $i=$i+2;
}
return
gzinflate(substr($gzData,$i,-8));
}
else return
false;
}
?>
3
spikeles_ at hotmail dot com
17 年前
这可以用来解压缩由 Java 类 java.util.zip.Deflater 压缩的流,但是您必须删除它前面的 2 个字节。(类似于上面的评论)

<?php $result = gzinflate(substr($compressedData, 2)); ?>
1
niblett at gmail dot com
12 年前
使用可选文件名头检测的替代方案
<?php
function gzdecode($data) {

// 检查 FLG 中是否设置了文件名字段,它是第 4 个字节
$hex = bin2hex($data);

$flg = (int)hexdec(substr($hex, 6, 2));

// 删除标题
$hex = substr($hex, 20);

$ret = '';
if ( (
$flg & 0x8) == 8 ){
print
"ello";
for (
$i = 0; $i < strlen($hex); $i += 2 ){
$value = substr($hex, $i, 2);
if (
$value == '00' ){
$ret = substr($hex, ($i+2));
break;
}
}
}
return
gzinflate(pack('H*', $ret));
}
?>
1
akniep at rayo dot info
11 年前
使用可选的第二个参数 $length 时要小心!
在我们的测试中 - 至少在某些情况下 - 我们无法确定此参数的实际用途,此外,它会导致脚本无法解压缩压缩数据或由于内存问题而崩溃。

示例
尝试解压缩来自网站的压缩数据时,我们实际上无法找到 $length 的值(除了 0),以使 gzinflate 正常工作... 而没有第二个参数(或将其设置为 0)gzinflate 完美运行

<?php
// -----------------------------------------------------------------------
// 测试 1 正常工作,无问题。内存峰值使用情况:压缩前:24.787 kB;压缩后:24.844 kB。
gzinflate( substr($deflated_body, 10) );

// -----------------------------------------------------------------------
// 以下所有三个测试都失败,并发出警告。内存峰值使用情况:压缩前:24.787 kB;压缩后:298.262 kB。
gzinflate( substr($deflated_body, 10), 200 * strlen($deflated_body) );
gzinflate( substr($deflated_body, 10), 32768 * strlen($deflated_body) );
gzinflate( substr($deflated_body, 10), 11000 );
gzinflate( substr($deflated_body, 10), 280000000 ); // PHP 内存限制设置为 300MB (memory_limit=300M)
=>
Warning: gzinflate() [function.gzinflate]: 内存不足 in [...]

// -----------------------------------------------------------------------
// 最后一个测试以致命错误失败。内存峰值使用情况:压缩前:24.787 kB;压缩后:? (> 300M)。
gzinflate( substr($deflated_body, 10), 300000000 ); // PHP 内存限制设置为 300MB (memory_limit=300M)
=>
Fatal error: 允许的内存大小为 314572800 字节,已用尽 (尝试分配 300000000 字节) in
?>

简而言之:我们无法确定某些情况下第二个参数的实际使用方式。
使用第二个参数 $length 时要小心!
-4
John
16 年前
当检索 mod_deflate gzip 压缩的内容并使用 gzinflate() 解码数据时,请务必从检索到的内容中删除前 11 个字符。

<?php $dec = gzinflate(substr($enc,11)); ?>
To Top