PHP Conference Japan 2024

gzuncompress

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

gzuncompress解壓縮壓縮字串

描述

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

此函式會解壓縮壓縮的字串。

參數

data

gzcompress() 壓縮的資料。

max_length

要解碼的資料最大長度。

傳回值

原始未壓縮資料,若發生錯誤則傳回 false

如果未壓縮的資料長度超過壓縮輸入 data 長度的 32768 倍,或者超過可選參數 max_length,則函式會傳回錯誤。

範例

範例 1:gzuncompress() 範例

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

參見

新增註解

使用者貢獻的註解 7 個註解

16
heavyccasey at gmail dot com
17 年前
請注意,gzuncompress() 可能無法解壓縮某些壓縮字串,並傳回資料錯誤。

問題可能是外部壓縮字串結尾的校驗和是 CRC32,而不是 PHP 預期的 Adler-32。

解決方法
<?php
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);
}
?>
14
anonymous at dekho-ji dot com
11 年前
若要在 PHP 程式碼中解碼/解壓縮收到的 HTTP POST 資料,要求來自 Java/Android 應用程式透過 HTTP POST GZIP/DEFLATE 壓縮格式的資料

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";

希望這有幫助。如果這為您節省了許多努力和時間,請按讚。
6
MagicalTux at php dot net
13 年前
嗨,我為那些 gzuncompress() 無法提取的壓縮字串找到了一個替代方案。

它比以前的選項好一點,因為它不會建立任何暫存檔,但必須以 base64 編碼字串,這表示它不會像原生對應項那麼快 (可能將會是 gzdecode())

<?php
if (!function_exists('gzdecode')) {
function
gzdecode($string) { // 不支援第二個引數
return file_get_contents('compress.zlib://data:who/cares;base64,'. base64_encode($string));
}
}
?>
4
gabriel at bumpt dot n-et
17 年前
若要在 PHP 中解壓縮使用 MySQL 的 COMPRESS() 函式壓縮的字串,您需要捨棄二進位資料的前四個位元組。

<?php

/*
* 範例:
*
* insert into mytable (myfield, ...) values (COMPRESS('foobar'), ...)
*
* 然後:
*/
$compressed = //...從 mytable 中選取 myfield where...
/*
* 然後:
*/
$uncompressed = gzuncompress(substr($compressed, 4));
?>

當然,您可以使用 MySQL 的 UNCOMPRESS() 函式。
我只是提供一個替代方法。
2
squeegee
15 年前
一種解壓縮檔案中 zlib 壓縮資料的方法,而無需先讀取檔案再進行 gzuncompress(或許這樣做會遇到記憶體問題),是編譯 zlib 中的 zpipe.c 程式碼 ( http://www.zlib.net/zpipe.c ) ...

在 Linux 等系統上

# gcc -lz -o zpipe zpipe.c

# cp zpipe /usr/local/bin

然後執行以下操作

<?php

$uncompressed
= shell_exec("cat $compressed_file | zpipe -d");

?>
0
emanuele at fondani dot it
18 年前
請注意,手冊中指出輸入參數必須是使用 gzcompress() 壓縮的字串,因此不保證可以解壓縮任何 zlib 壓縮的字串。
我在解壓縮 PDF 檔案中的某些壓縮字串時意識到這一點。 gzuncompress() 函數會產生資料錯誤,但是可以使用其他 zlib 解壓縮器成功解壓縮該字串。

更多資訊請參閱此處
http://bugs.php.net/?id=39616
-2
chappy at citromail dot hu
18 年前
讀取 ID3v2.3+ 標籤非常有用,因為這些標籤的幀可能已壓縮。 Zlib 壓縮幀佈局 (ID3v2.3)

描述符大小
-------------------
幀標頭
幀 ID:4 個位元組
幀大小 (完整幀大小 - 幀標頭大小):4 個位元組
幀標誌:2 個位元組
第二個位元組的第 7 位必須為 1 (例如:%1xy00000)
幀內容解壓縮大小:4 個位元組
--------------------
幀內容
以「幀大小」描述的壓縮字串

<?php
$frame
="[從 mp3 檔案讀取]";
$frame_id=substr($frame,0,4);
/*....*/
$cs=substr($frame,10,4);
$checksize=$cs[3]*16777216+$cs[2]*65536+$cs[1]*256+$cs[0];

$content=substr($frame,14,$contentsize);
$content=gzuncompress($content);
if(
strlen($content)!=$checksize){
echo
'解壓縮幀資料時發生錯誤<br>';
}
echo
$content;
?>
To Top