gzuncompress
(PHP 4 >= 4.0.1, PHP 5)
gzuncompress — Распаковывает строку
Описание
string gzuncompress
( string $data
[, int $length
] )
Распаковывает строку.
Список параметров
- data
-
Данные, сжатые функцией gzcompress().
- length
-
Максимальная длина данных для распаковки.
Возвращаемые значения
Распакованные данные или FALSE в случае ошибки.
Функция сообщит об ошибке также в случае, когда распакованные данные длиннее в более, чем 32768 или length раз сжатых.
Коментарии
Reading an ID3v2.3+ tag it is versy useful, because these tag's frames might be compressed. Zlib compressed frame layout (ID3v2.3):
Descriptior Size
-------------------
Frameheader:
Frame id: 4 bytes
Frame size (full frame size - frameheader size): 4 bytes
Frame flags: 2 bytes
The 2nd byte's 7th bit must be 1 (e.g.: %1xy00000)
Frame content decrompessed size: 4 bytes
--------------------
Framecontent:
Compressed string described in 'frame size'
<?php
$frame="[read from a mp3 file]";
$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 'Error whil uncrompessing frame data<br>';
}
echo $content;
?>
Note that the manual states that the input parameter must be a string compressed with gzcompress(), so it is not guaranteed that it will compress ANY zlib compressed string.
I realized this while decompressing some compressed string in a pdf file. The gzuncompress() function produces a data error, but the string can be successfully decompressed with other zlib decompressors.
More info here:
http://bugs.php.net/?id=39616
To uncompress in PHP a string that has been compressed using MySQL's COMPRESS() function, you need to discard the first four bytes of the binary data:
<?php
/*
* Example:
*
* insert into mytable (myfield, ...) values (COMPRESS('foobar'), ...)
*
* then:
*/
$compressed = //...select myfield from mytable where...
/*
* then:
*/
$uncompressed = gzuncompress(substr($compressed, 4));
?>
Of course, you can use MySQL's UNCOMPRESS() function.
I was just providing an alternate method.
Note that gzuncompress() may not decompress some compressed strings and return a Data Error.
The problem could be that the outside compressed string has a CRC32 checksum at the end of the file instead of Adler-32, like PHP expects.
Workaround:
<?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);
}
?>
One way to uncompress zlib-compressed data that is in a file without first reading in the file and then gzuncompressing it (maybe you have memory problems doing it that way) is to compile the zpipe.c program from zlib ( http://www.zlib.net/zpipe.c )...
on linux, etc:
# gcc -lz -o zpipe zpipe.c
# cp zpipe /usr/local/bin
Then do this
<?php
$uncompressed = shell_exec("cat $compressed_file | zpipe -d");
?>
Hi, I got an alternative for those zipped strings that gzuncompress() cannot extract.
It is a bit better than previous options as it do not create any temporary files, but it has to encode the string in base64, meaning it won't be as fast as a native equivalent (which is probably going to be gzdecode())
<?php
if (!function_exists('gzdecode')) {
function gzdecode($string) { // no support for 2nd argument
return file_get_contents('compress.zlib://data:who/cares;base64,'. base64_encode($string));
}
}
?>
To decode / uncompress the received HTTP POST data in PHP code, request data coming from Java / Android application via HTTP POST GZIP / DEFLATE compressed format
1) Data sent from Java Android app to PHP using DeflaterOutputStream java class and received in PHP as shown below
echo gzinflate( substr($HTTP_RAW_POST_DATA,2,-4) ) . PHP_EOL . PHP_EOL;
2) Data sent from Java Android app to PHP using GZIPOutputStream java class and received in PHP code as shown below
echo gzinflate( substr($HTTP_RAW_POST_DATA,10,-8) ) . PHP_EOL . PHP_EOL;
From Java Android side (API level 10+), data being sent in DEFLATE compressed format
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();
On PHP side (v 5.3.1), code for decompressing this DEFLATE data will be
echo substr($HTTP_RAW_POST_DATA,2,-4);
From Java Android side (API level 10+), data being sent in GZIP compressed format
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();
On PHP side (v 5.3.1), code for decompressing this GZIP data will be
echo substr($HTTP_RAW_POST_DATA,10,-8);
Useful PHP code for printing out compressed data using all available formats.
$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";
Hope this helps. Please ThumbsUp if this saved you a lot of effort and time.