圧縮フィルタ

圧縮ストリーム を用いれば ローカルファイルシステム上に gzip や bz2 と互換性のある圧縮ファイルを 作成することができます。しかし、これはネットワーク越しの圧縮機能を 持っておらず、また非圧縮ストリームを圧縮されたストリームに変換することも できません。その点、圧縮フィルタはどんなストリームリソースでもどんな場合 でも適用可能です。

注意: 圧縮フィルタは、gzip のようなコマンドライン ユーティリティで使われるヘッダを生成しません。 これらのフィルタは、(ヘッダ部を除いた)データストリームの本体のみを 圧縮・展開するものです。

zlib.deflate (圧縮) と zlib.inflate (展開) は、 » RFC 1951 で述べられている圧縮方法を 実装したものです。deflate フィルタには、次の 3 つの パラメータを連想配列形式で渡すことができます: level は、圧縮の度合いを 1から9 までで表した ものです。数字が大きいほど圧縮後のサイズが小さくなりますが、そのぶん 処理時間が長くかかります。次の2つの値は特別な意味を持ちます。 0 (一切圧縮しない)、そして -1 (zlib のデフォルト設定 -- 現在は 6)。 window は、圧縮用ループバックウィンドウのサイズを (2 を底とする)対数で指定します。大きな値 (15 -- つまり 32768 バイトまで 引き上げる) を指定するとメモリをふんだんに利用してより小さく圧縮されます。 一方、小さな値 (9 -- つまり 512 バイトまで絞り込む) を指定すると、圧縮の 効率は落ちますがメモリの消費量を抑えられます。値を指定しなかった際の window の初期値は、現在 15 です。 memory は、作業用の一時メモリをどの程度割り当てるかを 指定します。1 (最小限) から 9 (最大限) の間で指定できます。この値は 圧縮の速度のみに影響し、圧縮後のデータのサイズには影響しません。

注意: level は一番よく使われるパラメータなので、このパラメータについては (配列形式ではなく)直接整数値として設定することも可能にしています。

zlib.* 圧縮フィルタが有効になるのは、PHP バージョン 5.1.0zlib サポートが有効な場合です。 また、» PECL から » zlib_filter パッケージをインストールすることで、バージョン 5.0.x でも利用可能になります。

例1 zlib.deflatezlib.inflate

<?php
$params 
= array('level' => 6'window' => 15'memory' => 9);

$original_text "This is a test.\nThis is only a test.\nThis is not an important string.\n";
echo 
"もとのテキストの長さは " strlen($original_text) . " 文字です。\n";

$fp fopen('test.deflated''w');
stream_filter_append($fp'zlib.deflate'STREAM_FILTER_WRITE$params);
fwrite($fp$original_text);
fclose($fp);

echo 
"圧縮後のファイルの大きさは " filesize('test.deflated') . " バイトです。\n";
echo 
"もとのテキストは:\n";
/* readfile と zlib.inflate を利用し、メモリ上で展開します */
readfile('php://filter/zlib.inflate/resource=test.deflated');

/* 出力:

もとのテキストの長さは 70 文字です。
圧縮後のファイルの大きさは 56 バイトです。
もとのテキストは:
This is a test.
This is only a test.
This is not an important string.

 */
?>

例2 zlib.deflate のシンプルな例

<?php
$original_text 
"This is a test.\nThis is only a test.\nThis is not an important string.\n";
echo 
"もとのテキストの長さは " strlen($original_text) . " 文字です。\n";

$fp fopen('test.deflated''w');
/* この "6" は、パラメータ "level" が 6 であるということ */
stream_filter_append($fp'zlib.deflate'STREAM_FILTER_WRITE6);
fwrite($fp$original_text);
fclose($fp);

echo 
"圧縮後のファイルの大きさは " filesize('test.deflated') . " バイトです。\n";

/* 出力:

もとのテキストの長さは 70 文字です。
圧縮後のファイルの大きさは 56 バイトです。

 */
?>

bzip2.compressbzip2.decompress は、上で示した zlib フィルタと同じような動作をします。 bzip2.compress フィルタには、次の 2 つの パラメータを連想配列形式で渡すことができます: blocks は 1 から 9 までの整数値を設定します。 これは一時領域として割り当てるメモリのサイズを 100kバイトブロックの 数で示したものです。 work も整数値で、0 から 250 までの値を設定します。 これは、通常の圧縮方法がうまくいかなかった際に、どのくらい再試行した後で 速度の遅い(ただしより確実な)方法に切りかえるかを示します。 このパラメータは圧縮の速度のみに影響します。圧縮後のデータのサイズや 圧縮時のメモリ使用量は変わりません。0 を指定した場合は、bzip ライブラリの 初期設定値が利用されます。 bzip2.decompress フィルタには 1 つのパラメータを 渡すことができます。このパラメータは普通に論理型の値として渡すことも できますし、連想配列形式で small という名前の 要素として渡すこともできます。 smallTRUE に設定した場合、bzip ライブラリは メモリ使用量をできるだけ抑えるようになり、その分、処理速度は遅くなります。

bzip2.* 圧縮フィルタが有効になるのは、PHP バージョン 5.1.0bz2 サポートが有効な場合です。 また、» PECL から » bz2_filter パッケージをインストールすることで、バージョン 5.0.x でも利用可能になります。

例3 bzip2.compressbzip2.decompress

<?php
$param 
= array('blocks' => 9'work' => 0);

echo 
"もとのファイルの大きさは " filesize('LICENSE') . " バイトです。\n";

$fp fopen('LICENSE.compressed''w');
stream_filter_append($fp'bzip2.compress'STREAM_FILTER_WRITE$param);
fwrite($fpfile_get_contents('LICENSE'));
fclose($fp);

echo 
"圧縮後のファイルの大きさは " filesize('LICENSE.compressed') . " バイトです。\n";

/* 出力:

もとのファイルの大きさは 3288 バイトです。
圧縮後のファイルの大きさは 1488 バイトです。

 */
?>