NOTE:
doing like this and so on
<?php
file_put_contents('output.gz', gzencode( file_get_contents('input.file'),9));
?>
(complete file reading)
may cause memory overflow (Fatal error: Allowed memory size of ..), so it's better to read by parts/bytes.
gzencode
(PHP 4 >= 4.0.4, PHP 5)
gzencode — gzip 圧縮された文字列を作成する
説明
この関数は、入力 data を gzip プログラムの出力と互換性のある形式で圧縮 して返します。
GZIPファイルフォーマットに関する詳細な情報については、次のドキュ メントを参照ください。 » GZIP file format specification version 4.3 (RFC 1952)
パラメータ
- data
-
エンコードするデータを指定します
- level
-
圧縮レベルを指定します。 圧縮をしない場合に 0、最大限の圧縮を行う場合に9を指定可能です。 指定されない場合のデフォルト圧縮レベルは、 zlib ライブラリのデフォルト圧縮レベルになります。
- encoding_mode
-
エンコーディングモードを指定します。 FORCE_GZIP (デフォルト) もしくは FORCE_DEFLATE を指定可能です。
もし FORCE_DEFLATE を使用した場合、 crc32 チェックサムが付加されていない gzip ファイルヘッダに続いて標準的な zlib 収縮文字列 (zlib ヘッダを含む) を受け取るでしょう。
返り値
エンコードされた文字列、もしくはエラー発生時に FALSE
変更履歴
| バージョン | 説明 |
|---|---|
| 4.2.0 | パラメータ encoding_mode が追加されました。 |
例
結果データは標準的な .gz ファイルを構成するための適当なヘッダとデータ構造を含みます。
例1 gzip ファイルの生成
<?php
$data = implode("", file("bigfile.txt"));
$gzdata = gzencode($data, 9);
$fp = fopen("bigfile.txt.gz", "w");
fwrite($fp, $gzdata);
fclose($fp);
?>
参考
- gzdecode() - gzip 圧縮された文字列をデコードする
- gzdeflate() - 文字列を deflate 圧縮する
- gzinflate() - deflate圧縮された文字列を解凍する
- gzuncompress() - 圧縮された文字列を解凍する
- gzcompress() - 文字列を圧縮する
gzencode
23-Jan-2009 08:29
30-Apr-2008 08:58
Aaron G. 07-Aug-2004 03:29 posted the excellent function gzdecode() (SEE BELOW)
BUGFIX: Change: if($flags & 1) to ... if($flags & 2)
Unfortunately the function gzencode() does NOT append a CRC! So the previous version worked with output of gzencode but not with output of the gzip program itself.
15-Apr-2008 12:47
here is my clean up of supaplex %at% pcbkits %d0t% c0m
submission above.
function alt_gzdecode($gzdatadecode) {
// seed with microseconds since last "whole" second.
mt_srand((float)microtime()*1000000);
$eh="/tmp/php-" . md5(mt_rand(0,mt_getrandmax())) . ".gz";
if(file_exists($eh)){
$gzf=fopen($eh,"w");
fwrite($gzf,$gzdatadecode);
fclose($gzf);
$gzf = gzopen ($eh, "r");
$gzdatadecode=gzpassthru($gzf);
unlink($eh);
return $gzdatadecode;
}else{
return 'File '.$eh.' was not found.';
}
}
04-Aug-2006 01:52
Correct is:
<?php
file_put_contents('output.gz', gzencode( file_get_contents('input.file'),9));
?>
07-Aug-2004 01:29
<?php
function gzdecode($data) {
$len = strlen($data);
if ($len < 18 || strcmp(substr($data,0,2),"\x1f\x8b")) {
return null; // Not GZIP format (See RFC 1952)
}
$method = ord(substr($data,2,1)); // Compression method
$flags = ord(substr($data,3,1)); // Flags
if ($flags & 31 != $flags) {
// Reserved bits are set -- NOT ALLOWED by RFC 1952
return null;
}
// NOTE: $mtime may be negative (PHP integer limitations)
$mtime = unpack("V", substr($data,4,4));
$mtime = $mtime[1];
$xfl = substr($data,8,1);
$os = substr($data,8,1);
$headerlen = 10;
$extralen = 0;
$extra = "";
if ($flags & 4) {
// 2-byte length prefixed EXTRA data in header
if ($len - $headerlen - 2 < 8) {
return false; // Invalid format
}
$extralen = unpack("v",substr($data,8,2));
$extralen = $extralen[1];
if ($len - $headerlen - 2 - $extralen < 8) {
return false; // Invalid format
}
$extra = substr($data,10,$extralen);
$headerlen += 2 + $extralen;
}
$filenamelen = 0;
$filename = "";
if ($flags & 8) {
// C-style string file NAME data in header
if ($len - $headerlen - 1 < 8) {
return false; // Invalid format
}
$filenamelen = strpos(substr($data,8+$extralen),chr(0));
if ($filenamelen === false || $len - $headerlen - $filenamelen - 1 < 8) {
return false; // Invalid format
}
$filename = substr($data,$headerlen,$filenamelen);
$headerlen += $filenamelen + 1;
}
$commentlen = 0;
$comment = "";
if ($flags & 16) {
// C-style string COMMENT data in header
if ($len - $headerlen - 1 < 8) {
return false; // Invalid format
}
$commentlen = strpos(substr($data,8+$extralen+$filenamelen),chr(0));
if ($commentlen === false || $len - $headerlen - $commentlen - 1 < 8) {
return false; // Invalid header format
}
$comment = substr($data,$headerlen,$commentlen);
$headerlen += $commentlen + 1;
}
$headercrc = "";
if ($flags & 1) {
// 2-bytes (lowest order) of CRC32 on header present
if ($len - $headerlen - 2 < 8) {
return false; // Invalid format
}
$calccrc = crc32(substr($data,0,$headerlen)) & 0xffff;
$headercrc = unpack("v", substr($data,$headerlen,2));
$headercrc = $headercrc[1];
if ($headercrc != $calccrc) {
return false; // Bad header CRC
}
$headerlen += 2;
}
// GZIP FOOTER - These be negative due to PHP's limitations
$datacrc = unpack("V",substr($data,-8,4));
$datacrc = $datacrc[1];
$isize = unpack("V",substr($data,-4));
$isize = $isize[1];
// Perform the decompression:
$bodylen = $len-$headerlen-8;
if ($bodylen < 1) {
// This should never happen - IMPLEMENTATION BUG!
return null;
}
$body = substr($data,$headerlen,$bodylen);
$data = "";
if ($bodylen > 0) {
switch ($method) {
case 8:
// Currently the only supported compression method:
$data = gzinflate($body);
break;
default:
// Unknown compression method
return false;
}
} else {
// I'm not sure if zero-byte body content is allowed.
// Allow it for now... Do nothing...
}
// Verifiy decompressed size and CRC32:
// NOTE: This may fail with large data sizes depending on how
// PHP's integer limitations affect strlen() since $isize
// may be negative for large sizes.
if ($isize != strlen($data) || crc32($data) != $datacrc) {
// Bad format! Length or CRC doesn't match!
return false;
}
return $data;
}
?>
03-Apr-2002 10:53
The 10 byte string in gzencode is the standard gzip header. The first two bytes (1f 8b) define the return as a gzip file, the third byte (08) means that the body is compressed using the "deflate" algorithm. The rest is padding (00)'s.
Technically, I believe one should check if the third byte is hex 08 and if so strip off the first ten bytes and last four bytes and run inflate on it. The last four bytes are file size and checksum bits.
In practice, you can get away with just stripping the first 10 bytes and running inflate on it.
Hope this helps,
terry
15-Feb-2002 02:28
Well, I was looking for a gzdecode too and didn't consider the temporary file example above to be very elegant.
However, as is noted in the very first comment: gzencode() only adds a 10 byte header.
I don't quite know what this header is supposed to be used for, but gzinflate() certainly doesn't like it, so I stripped it off:
function my_gzdecode($string) {
$string = substr($string, 10);
return gzinflate($string);
}
That's useful to read HTTP-Connections that were compressed by mod_gzip.
--
Henryk Pltz
Gre aus Berlin
09-Sep-2001 07:14
function alt_gzdecode($str) {
// seed with microseconds since last "whole" second
mt_srand((float)microtime()*1000000);
$eh="/tmp/php-" . md5(mt_rand(0,mt_getrandmax())) . ".gz";
$fd=fopen($eh,"w");
fwrite($fd,$str);
fclose($fd);
unset($str);
$fd = gzopen ($eh, "r");
while (1==1) {
$s=gzread($fd,10240);
if ("$s" == "") {
break;
}
$str=$str . $s;
}
unlink($eh);
return $str;
}
09-Sep-2001 06:48
I was almost discouraged when I didn't find a gzdecode() function! However, fear not, for I'll contribute my work... :)
function alt_gzdecode($str) {
// seed with microseconds since last "whole" second.
mt_srand((float)microtime()*1000000);
$eh="/tmp/php-" . md5(mt_rand(0,mt_getrandmax())) . ".gz";
$fd=fopen($eh,"w");
fwrite($fd,$str);
fclose($fd);
$fd = gzopen ($eh, "r");
$str=gzpassthru($fd);
unlink($eh);
return $str;
}
It's only ugly point is that it does not check to see if the file already exists. You may also have to adjust reference names like $str and $fd if they stomp on your code. (Sorry, but this is all you get atm! ;} ) If your conserned about a race condition, cry for a internal gzdecode() function that actualy functions...
I spent about 3 hours straight debugging this problem. I know the input data was valid, becuase I validated it with MD5() to compare to the md5's I had made of the input data before hand. I'm not sure whats up with gzuncompress or gzinflate, but this works in its place . . .
Enjoy!
