<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/filters.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ja',
  ),
  'this' => 
  array (
    0 => 'filters.compression.php',
    1 => '圧縮フィルタ',
    2 => '圧縮フィルタ',
  ),
  'up' => 
  array (
    0 => 'filters.php',
    1 => '利用できるフィルタのリスト',
  ),
  'prev' => 
  array (
    0 => 'filters.convert.php',
    1 => '変換フィルタ',
  ),
  'next' => 
  array (
    0 => 'filters.encryption.php',
    1 => '暗号化フィルタ',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ja',
    'path' => 'appendices/filters.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="filters.compression" class="section">
  <h2 class="title">圧縮フィルタ</h2>

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

  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <p class="simpara">
    圧縮フィルタは、<code class="literal">gzip</code> のようなコマンドライン
    ユーティリティで使われるヘッダを<em>生成しません</em>。
    これらのフィルタは、（ヘッダ部を除いた）データストリームの本体のみを
    圧縮・展開するものです。
   </p>
  </p></blockquote>

  <div class="section" id="filters.compression.zlib">
   <h2 class="title">zlib.deflate と zlib.inflate</h2>
   <p class="para">
    <code class="literal">zlib.deflate</code> (圧縮) と
    <code class="literal">zlib.inflate</code> (展開) は、
    <a href="https://datatracker.ietf.org/doc/html/rfc1951" class="link external">&raquo;&nbsp;RFC 1951</a> で述べられている圧縮方法を
    実装したものです。<code class="literal">deflate</code> フィルタには、次の 3 つの
    パラメータを連想配列形式で渡すことができます:
 
    <code class="parameter">level</code> は、圧縮の度合いを 1から9 までで表した
    ものです。数字が大きいほど圧縮後のサイズが小さくなりますが、そのぶん
    処理時間が長くかかります。次の2つの値は特別な意味を持ちます。
    0 (一切圧縮しない)、そして -1 (zlib のデフォルト設定 -- 現在は 6)。
 
    <code class="parameter">window</code> は、圧縮用ループバックウィンドウのサイズを
    （2 を底とする）対数で指定します。大きな値 (15 -- つまり 32768 バイトまで
    引き上げる) を指定するとメモリをふんだんに利用してより小さく圧縮されます。
    一方、小さな値 (9 -- つまり 512 バイトまで絞り込む) を指定すると、圧縮の
    効率は落ちますがメモリの消費量を抑えられます。値を指定しなかった際の
    <code class="parameter">window</code> の初期値は、現在 <code class="literal">15</code> です。
 
    <code class="literal">zlib.deflate</code> フィルタは
    <code class="literal">DEFLATE</code>、<code class="literal">ZLIB</code>、<code class="literal">GZIP</code>
    の 3 つの圧縮方法を実装しており、どれを使うかは
    <code class="parameter">window</code> パラメータの値で決まります。

    window パラメータの下位 4 ビットは、内部で使われる「ヒストリバッファ」の
    サイズを、2 を底とする対数で指定するもので、8 から 15 までの
    範囲を取ります。それ以外のビットの意味は、
    以下のとおりです。

    <ul class="itemizedlist">
     <li class="listitem">
      <p class="simpara">
       <code class="literal">DEFLATE</code> (<a href="https://datatracker.ietf.org/doc/html/rfc1951" class="link external">&raquo;&nbsp;RFC 1951</a>)
       は、ヘッダもチェックサムも持たない生の圧縮アルゴリズムです。
       window パラメータに -9 から -15 の範囲の値を指定した場合に、この圧縮が行われます。
       この圧縮アルゴリズムは、<code class="literal">zlib.deflate</code> フィルタが生成する
       すべてのフォーマットの基礎になっています。
       文字列を直接扱う関数としては、<span class="function"><a href="function.gzdeflate.php" class="function">gzdeflate()</a></span> と
       <span class="function"><a href="function.gzinflate.php" class="function">gzinflate()</a></span> が対応します。
      </p>
     </li>

     <li class="listitem">
      <p class="simpara">
       <code class="literal">ZLIB</code> (<a href="https://datatracker.ietf.org/doc/html/rfc1950" class="link external">&raquo;&nbsp;RFC 1950</a>)
       は、<code class="literal">DEFLATE</code> アルゴリズムを適用した上で、2 バイトのヘッダと、
       圧縮前のデータの Adler32 チェックサムをビッグエンディアンのバイトオーダーで
       格納した 4 バイトのトレーラーを追加します:
       <code class="literal"><div class="cdata"><pre>ZLIB = ZLIBHEADER(2B)  DEFLATE  ADLER32(4B)</pre></div></code>

       2 バイトのヘッダをビッグエンディアンの 16 ビット符号なし整数として読んだ値は、
       31 の倍数でなければなりません。
       window パラメータに 8 から 15 の範囲の値を指定した場合に、
       このフォーマットが生成されます。
       文字列を直接扱う関数としては、<span class="function"><a href="function.gzcompress.php" class="function">gzcompress()</a></span> と
       <span class="function"><a href="function.gzuncompress.php" class="function">gzuncompress()</a></span> が対応します。
      </p>
     </li>

     <li class="listitem">
      <p class="simpara">
       <code class="literal">GZIP</code> (<a href="https://datatracker.ietf.org/doc/html/rfc1952" class="link external">&raquo;&nbsp;RFC 1952</a>)
       は、<code class="literal">DEFLATE</code> アルゴリズムを適用した上で、ヘッダと、
       圧縮前のデータの <code class="literal">CRC32</code> チェックサムおよびその長さを、
       どちらもリトルエンディアンのバイトオーダーで格納したトレーラーを追加します:
       <code class="literal"><div class="cdata"><pre>GZIP = GZIPHEADER(10B)  DEFLATE  CRC32(4B)  LENGTH(4B)</pre></div></code>

       これが <code class="literal">.gz</code> ファイルのフォーマットです。
       <code class="literal">GZIPHEADER</code> には、順に
       <code class="literal">GZIP</code> シグネチャ (<code class="literal">\x1f\x8B</code>)、
       圧縮メソッド (<code class="literal">\x08</code>)、値がゼロのフラグバイト、
       値がゼロの 4 バイトの更新時刻、圧縮レベルに応じた extra-flags バイト、
       そして現在のオペレーティングシステム
       (<code class="literal">\x00</code> = FAT ファイルシステム、
       <code class="literal">\x03</code> = Unix など) が格納されます。
       window パラメータに 9+16=25 から 15+16=31 の範囲の値を指定した場合に、
       このフォーマットが生成されます。
       圧縮前のデータの長さには 4GB という上限があることに注意してください。
       この上限を超えた場合、<code class="literal">LENGTH</code> の部分には実際の長さを
       2^32 で割った余りだけが格納されます。
       文字列を直接扱う関数としては、<span class="function"><a href="function.gzencode.php" class="function">gzencode()</a></span> と
       <span class="function"><a href="function.gzdecode.php" class="function">gzdecode()</a></span> が対応します。また
       <span class="function"><a href="function.gzopen.php" class="function">gzopen()</a></span> 関数を使うと、<code class="literal">.gz</code>
       ファイルの読み書きができます。
      </p>
     </li>
    </ul>

    <code class="literal">zlib.inflate</code> フィルタで指定できるのは
    <code class="parameter">window</code> パラメータだけで、それ以外のパラメータ
    (<code class="parameter">memory</code>、<code class="parameter">level</code>) は無視されます。
    $W をヒストリバッファのサイズの 2 を底とする対数とすると、展開時には
    2^$W バイトが確保されます。ZLIB フォーマットの場合、この値はヘッダに記録された
    値以上でなければならず、展開時にチェックされます。それ以外のフォーマットの場合は、
    データ中に実際に現れるマッチ距離をまかなえる大きさであれば十分です。
    範囲は 9 ≤ $W ≤ 15 です。値がわからない場合は $W=15 にしておくのが安全です。

    <ul class="itemizedlist">
     <li class="listitem">
      <p class="simpara">
       <code class="literal">DEFLATE</code> (<a href="https://datatracker.ietf.org/doc/html/rfc1951" class="link external">&raquo;&nbsp;RFC 1951</a>):
       window=-$W を指定します。$W には、圧縮時に使った値以上を指定します。
       値がわからない場合は window=-15 を指定してください。
      </p>
     </li>

     <li class="listitem">
      <p class="simpara">
       <code class="literal">ZLIB</code> (<a href="https://datatracker.ietf.org/doc/html/rfc1950" class="link external">&raquo;&nbsp;RFC 1950</a>):
       window=$W を指定します。$W の値は ZLIB ヘッダから取得できます。
       値がわからない場合は window=15 を指定してください。
      </p>
     </li>

     <li class="listitem">
      <p class="simpara">
       <code class="literal">GZIP</code> (<a href="https://datatracker.ietf.org/doc/html/rfc1952" class="link external">&raquo;&nbsp;RFC 1952</a>):
       window=$W+16 を指定します。GZIP ヘッダは window サイズを保持していないので、
       圧縮時に使った値がわからない場合は window=31 を指定してください。
      </p>
     </li>

     <li class="listitem">
      <p class="simpara">
       <code class="literal">ZLIB or GZIP</code>:
       ヘッダを自動で検出させるには window=$W+32 を指定します。こうすると
       どちらのフォーマットも認識して展開できます。
       window=15+32=47 にしておくのが安全です。
      </p>
     </li>
    </ul>

    <code class="parameter">memory</code> は、作業用の一時メモリをどの程度割り当てるかを
    指定します。1 (最小限) から 9 (最大限) の間で指定できます。この値は
    圧縮の速度のみに影響し、圧縮後のデータのサイズには影響しません。
  </p>

  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <p class="simpara">
    level は一番よく使われるパラメータなので、このパラメータについては
    （配列形式ではなく）直接整数値として設定することも可能にしています。
   </p>
  </p></blockquote>

  <p class="simpara">
    <a href="ref.zlib.php" class="link">zlib</a> サポートが有効な場合、
    zlib.* 圧縮フィルタが利用可能になります。
  </p>

  <div class="example" id="example-1">
   <p><strong>例1 
    <code class="literal">zlib.deflate</code> と
    <code class="literal">zlib.inflate</code>
   </strong></p>
   <div class="example-contents">
<div class="phpcode"><pre><code style="color: #000000"><span style="color: #0000BB">&lt;?php
$params </span><span style="color: #007700">= array(</span><span style="color: #DD0000">'level' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">6</span><span style="color: #007700">, </span><span style="color: #DD0000">'window' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">15</span><span style="color: #007700">, </span><span style="color: #DD0000">'memory' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">9</span><span style="color: #007700">);

</span><span style="color: #0000BB">$original_text </span><span style="color: #007700">= </span><span style="color: #DD0000">"This is a test.\nThis is only a test.\nThis is not an important string.\n"</span><span style="color: #007700">;
echo </span><span style="color: #DD0000">"もとのテキストの長さは " </span><span style="color: #007700">. </span><span style="color: #0000BB">strlen</span><span style="color: #007700">(</span><span style="color: #0000BB">$original_text</span><span style="color: #007700">) . </span><span style="color: #DD0000">" 文字です。\n"</span><span style="color: #007700">;

</span><span style="color: #0000BB">$fp </span><span style="color: #007700">= </span><span style="color: #0000BB">fopen</span><span style="color: #007700">(</span><span style="color: #DD0000">'test.deflated'</span><span style="color: #007700">, </span><span style="color: #DD0000">'w'</span><span style="color: #007700">);
</span><span style="color: #0000BB">stream_filter_append</span><span style="color: #007700">(</span><span style="color: #0000BB">$fp</span><span style="color: #007700">, </span><span style="color: #DD0000">'zlib.deflate'</span><span style="color: #007700">, </span><span style="color: #0000BB">STREAM_FILTER_WRITE</span><span style="color: #007700">, </span><span style="color: #0000BB">$params</span><span style="color: #007700">);
</span><span style="color: #0000BB">fwrite</span><span style="color: #007700">(</span><span style="color: #0000BB">$fp</span><span style="color: #007700">, </span><span style="color: #0000BB">$original_text</span><span style="color: #007700">);
</span><span style="color: #0000BB">fclose</span><span style="color: #007700">(</span><span style="color: #0000BB">$fp</span><span style="color: #007700">);

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

</span><span style="color: #FF8000">/* 生成される出力:

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

 */
</span><span style="color: #0000BB">?&gt;</span></code></pre></div>
    </div>

   </div>

  <div class="example" id="example-2">
   <p><strong>例2 
    <code class="literal">zlib.deflate</code> のシンプルな例
   </strong></p>
   <div class="example-contents">
<div class="phpcode"><pre><code style="color: #000000"><span style="color: #0000BB">&lt;?php
$original_text </span><span style="color: #007700">= </span><span style="color: #DD0000">"This is a test.\nThis is only a test.\nThis is not an important string.\n"</span><span style="color: #007700">;
echo </span><span style="color: #DD0000">"もとのテキストの長さは " </span><span style="color: #007700">. </span><span style="color: #0000BB">strlen</span><span style="color: #007700">(</span><span style="color: #0000BB">$original_text</span><span style="color: #007700">) . </span><span style="color: #DD0000">" 文字です。\n"</span><span style="color: #007700">;

</span><span style="color: #0000BB">$fp </span><span style="color: #007700">= </span><span style="color: #0000BB">fopen</span><span style="color: #007700">(</span><span style="color: #DD0000">'test.deflated'</span><span style="color: #007700">, </span><span style="color: #DD0000">'w'</span><span style="color: #007700">);
</span><span style="color: #FF8000">/* この "6" は、パラメータ "level" が 6 であるということ */
</span><span style="color: #0000BB">stream_filter_append</span><span style="color: #007700">(</span><span style="color: #0000BB">$fp</span><span style="color: #007700">, </span><span style="color: #DD0000">'zlib.deflate'</span><span style="color: #007700">, </span><span style="color: #0000BB">STREAM_FILTER_WRITE</span><span style="color: #007700">, </span><span style="color: #0000BB">6</span><span style="color: #007700">);
</span><span style="color: #0000BB">fwrite</span><span style="color: #007700">(</span><span style="color: #0000BB">$fp</span><span style="color: #007700">, </span><span style="color: #0000BB">$original_text</span><span style="color: #007700">);
</span><span style="color: #0000BB">fclose</span><span style="color: #007700">(</span><span style="color: #0000BB">$fp</span><span style="color: #007700">);

echo </span><span style="color: #DD0000">"圧縮後のファイルの大きさは " </span><span style="color: #007700">. </span><span style="color: #0000BB">filesize</span><span style="color: #007700">(</span><span style="color: #DD0000">'test.deflated'</span><span style="color: #007700">) . </span><span style="color: #DD0000">" バイトです。\n"</span><span style="color: #007700">;

</span><span style="color: #FF8000">/* 生成される出力:

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

 */
</span><span style="color: #0000BB">?&gt;</span></code></pre></div>
    </div>

   </div>
  </div>

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

  <p class="simpara">
    <a href="ref.bzip2.php" class="link">bz2</a> サポートが有効な場合、
    bzip2.* 圧縮フィルタが利用可能になります。
  </p>

  <div class="example" id="example-3">
   <p><strong>例3 
    <code class="literal">bzip2.compress</code> と
    <code class="literal">bzip2.decompress</code>
   </strong></p>
   <div class="example-contents">
<div class="phpcode"><pre><code style="color: #000000"><span style="color: #0000BB">&lt;?php
$param </span><span style="color: #007700">= array(</span><span style="color: #DD0000">'blocks' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">9</span><span style="color: #007700">, </span><span style="color: #DD0000">'work' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">0</span><span style="color: #007700">);

echo </span><span style="color: #DD0000">"もとのファイルの大きさは " </span><span style="color: #007700">. </span><span style="color: #0000BB">filesize</span><span style="color: #007700">(</span><span style="color: #DD0000">'LICENSE'</span><span style="color: #007700">) . </span><span style="color: #DD0000">" バイトです。\n"</span><span style="color: #007700">;

</span><span style="color: #0000BB">$fp </span><span style="color: #007700">= </span><span style="color: #0000BB">fopen</span><span style="color: #007700">(</span><span style="color: #DD0000">'LICENSE.compressed'</span><span style="color: #007700">, </span><span style="color: #DD0000">'w'</span><span style="color: #007700">);
</span><span style="color: #0000BB">stream_filter_append</span><span style="color: #007700">(</span><span style="color: #0000BB">$fp</span><span style="color: #007700">, </span><span style="color: #DD0000">'bzip2.compress'</span><span style="color: #007700">, </span><span style="color: #0000BB">STREAM_FILTER_WRITE</span><span style="color: #007700">, </span><span style="color: #0000BB">$param</span><span style="color: #007700">);
</span><span style="color: #0000BB">fwrite</span><span style="color: #007700">(</span><span style="color: #0000BB">$fp</span><span style="color: #007700">, </span><span style="color: #0000BB">file_get_contents</span><span style="color: #007700">(</span><span style="color: #DD0000">'LICENSE'</span><span style="color: #007700">));
</span><span style="color: #0000BB">fclose</span><span style="color: #007700">(</span><span style="color: #0000BB">$fp</span><span style="color: #007700">);

echo </span><span style="color: #DD0000">"圧縮後のファイルの大きさは " </span><span style="color: #007700">. </span><span style="color: #0000BB">filesize</span><span style="color: #007700">(</span><span style="color: #DD0000">'LICENSE.compressed'</span><span style="color: #007700">) . </span><span style="color: #DD0000">" バイトです。\n"</span><span style="color: #007700">;

</span><span style="color: #FF8000">/* 生成される出力:

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

 */
</span><span style="color: #0000BB">?&gt;</span></code></pre></div>
    </div>

   </div>
  </div>
  </div><?php manual_footer($setup); ?>