<?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 => 'en',
  ),
  'this' => 
  array (
    0 => 'filters.compression.php',
    1 => 'Compression Filters',
    2 => 'Compression Filters',
  ),
  'up' => 
  array (
    0 => 'filters.php',
    1 => 'List of Available Filters',
  ),
  'prev' => 
  array (
    0 => 'filters.convert.php',
    1 => 'Conversion Filters',
  ),
  'next' => 
  array (
    0 => 'filters.encryption.php',
    1 => 'Encryption Filters',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'en',
    '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">Compression Filters</h2>

  <p class="simpara">
   While the <a href="wrappers.compression.php" class="link">Compression Wrappers</a>
   provide a way of creating
   gzip and bz2 compatible files on the local filesystem, they do not provide a 
   means for generalized compression over network streams, nor do they provide a 
   means to begin with a non-compressed stream and transition to a compressed one.  
   For this, a compression filter may be applied to any stream resource at any time.
  </p>

  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="simpara">
    Compression filters do <em>not</em> generate headers and trailers
    used by command line utilities such as <code class="literal">gzip</code>.  They only compress
    and decompress the payload portions of compressed data streams.
   </p>
  </p></blockquote>

  <div class="section" id="filters.compression.zlib">
   <h2 class="title">zlib.deflate and zlib.inflate</h2>
   <p class="para">
    <code class="literal">zlib.deflate</code> (compression) and
    <code class="literal">zlib.inflate</code> (decompression) are implementations of
    the compression methods described in <a href="https://datatracker.ietf.org/doc/html/rfc1951" class="link external">&raquo;&nbsp;RFC 1951</a>.
    The <code class="literal">deflate</code> filter takes up to three parameters passed as
    an associative array.  

    <code class="parameter">level</code> describes the compression
    strength to use (1-9).  Higher numbers will generally yield smaller payloads at
    the cost of additional processing time.  Two special compression levels also exist:
    0 (for no compression at all), and -1 (zlib internal default -- currently 6).

    <code class="parameter">window</code> is the base-2 log of the compression loopback window size.
    Higher values (up to 15 -- 32768 bytes) yield better compression at a cost of memory,
    while lower values (down to 9 -- 512 bytes) yield worse compression in a smaller memory footprint.
    Default <code class="parameter">window</code> size is currently <code class="literal">15</code>.

    The <code class="literal">zlib.deflate</code> filter implements the compression
    methods <code class="literal">DEFLATE</code>, <code class="literal">ZLIB</code> and
    <code class="literal">GZIP</code> depending on the value of the
    <code class="parameter">window</code> parameter.

    The 4 lower bits of the window parameter set the size of the internal
    “history buffer” used, being the base-2 logarithm of its size in a range
    from 8 up to 15. The meaning of the others bits of the window parameter
    can be set as described below.

    <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>)
       is a raw compression algorithm without header, without checksum. It is
       performed when the window parameter is set in the range from -9 up to
       -15. This compression algorithm is the base for all the formats
       generated by the <code class="literal">zlib.deflate</code> filter.
       The corresponding functions that operate directly on strings are
       <span class="function"><a href="function.gzdeflate.php" class="function">gzdeflate()</a></span> and <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>)
       applies the <code class="literal">DEFLATE</code> algorithm and adds a 2 bytes
       header and 4 bytes trailer containing the Adler32 checksum of the
       uncompressed data in big-endian byte order:
       <code class="literal"><div class="cdata"><pre>ZLIB = ZLIBHEADER(2B)  DEFLATE  ADLER32(4B)</pre></div></code>

       The 2 bytes header, read as 16 bit unsigned number in big-endian
       order, must be multiple of 31.
       This format is generated when the window parameter is set in the range
       from 8 up to 15.
       The corresponding functions that operate directly on strings are
       <span class="function"><a href="function.gzcompress.php" class="function">gzcompress()</a></span> and <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>)
       applies the <code class="literal">DEFLATE</code> algorithm adding an header and a
       trailer with the <code class="literal">CRC32</code> checksum of the uncompressed
       data and their length, both in little-endian byte ordering:
       <code class="literal"><div class="cdata"><pre>GZIP = GZIPHEADER(10B)  DEFLATE  CRC32(4B)  LENGTH(4B)</pre></div></code>

       This is the format of the <code class="literal">.gz</code> files, with the
       <code class="literal">GZIPHEADER</code> containing in the order the
       <code class="literal">GZIP</code> signature (<code class="literal">\x1f\x8B</code>), the
       compression method (<code class="literal">\x08</code>), a zero flag byte, a zero
       modification time on 4 bytes, an extra-flags byte that depends on the
       compression level, and the operating system set to the current system
       (<code class="literal">\x00</code> = FAT filesystem,
       <code class="literal">\x03</code> = Unix, etc.).
       This format is generated when the window parameter is set in the range
       from 9+16=25 up to 15+16=31. Note that there is a limit of 4GB to the
       maximum length of the uncompressed data; beyond this limit, only the
       modulo 2^32 of the actual length is stored in the <code class="literal">LENGTH</code> part.
       The corresponding functions that operate directly on strings are
       <span class="function"><a href="function.gzencode.php" class="function">gzencode()</a></span> and <span class="function"><a href="function.gzdecode.php" class="function">gzdecode()</a></span>; the
       <span class="function"><a href="function.gzopen.php" class="function">gzopen()</a></span> function allows to read and write
       <code class="literal">.gz</code> files.
      </p>
     </li>
    </ul>

    With the <code class="literal">zlib.inflate</code> filter, only the
    <code class="parameter">window</code> parameter is allowed; any other parameter
    (<code class="parameter">memory</code>, <code class="parameter">level</code>) is ignored.
    Be $W the base-2 log of the history buffer size, so that 2^$W bytes are
    allocated by the decompressor. For the ZLIB format this value must be
    greater or equal to the one recorded in the header, which is checked at
    decompression time; for the other formats it only has to be large enough
    for the match distances actually present in the data.
    The range is 9 ≤ $W ≤ 15. If unknown, $W=15 is the safer choice.

    <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>):
        use window=-$W, with $W being a value not less than that used for
        compression. If unknown, set 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>):
        use window=$W. The value of $W is available from the same ZLIB header,
        otherwise set 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>):
       use window=$W+16. A GZIP header carries no window size, so set
       window=31 unless the value used for compression is known.
      </p>
     </li>

     <li class="listitem">
      <p class="simpara">
       <code class="literal">ZLIB or GZIP</code>:
       use window=$W+32 for automatic header detection, so that both the
       formats can be recognized and decompressed; window=15+32=47 is the
       safer choice.
      </p>
     </li>
    </ul>

    <code class="parameter">memory</code> is a scale indicating how much work memory should be allocated.
    Valid values range from 1 (minimal allocation) to 9 (maximum allocation).  This memory allocation
    affects speed only and does not impact the size of the generated payload.
   </p>

   <blockquote class="note"><p><strong class="note">Note</strong>: 
    <p class="simpara">
     Because compression level is the most commonly used parameter, it may be alternatively
     provided as a simple integer value (rather than an array element).
    </p>
   </p></blockquote>

   <p class="simpara">
    zlib.* compression filters are available if
    <a href="ref.zlib.php" class="link">zlib</a> support is enabled.
   </p>

   <div class="example" id="example-1">
    <p><strong>Example #1 
     <code class="literal">zlib.deflate</code> and
     <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">"The original text is " </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">" characters long.\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">"The compressed file is " </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">" bytes long.\n"</span><span style="color: #007700">;
echo </span><span style="color: #DD0000">"The original text was:\n"</span><span style="color: #007700">;
</span><span style="color: #FF8000">/* Use readfile and zlib.inflate to decompress on the fly */
</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">/* Generates output:

The original text is 70 characters long.
The compressed file is 56 bytes long.
The original text was:
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>Example #2 
     <code class="literal">zlib.deflate</code> simple
    </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">"The original text is " </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">" characters long.\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">/* Here "6" indicates compression 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">"The compressed file is " </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">" bytes long.\n"</span><span style="color: #007700">;

</span><span style="color: #FF8000">/* Generates output:

The original text is 70 characters long.
The compressed file is 56 bytes long.

 */
</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 and bzip2.decompress</h2>
   <p class="simpara">
    <code class="literal">bzip2.compress</code> and
    <code class="literal">bzip2.decompress</code>
    work in the same manner as the zlib filters described above.

    The <code class="literal">bzip2.compress</code> filter accepts up to two parameters given as 
    elements of an associative array: 

    <code class="parameter">blocks</code> is an integer value
    from 1 to 9 specifying the number of 100kbyte blocks of memory to allocate for
    workspace. 

    <code class="parameter">work</code> is also an integer value ranging from
    0 to 250 indicating how much effort to expend using the normal compression method
    before falling back on a slower, but more reliable method.  Tuning this parameter
    effects only compression speed.  Neither size of compressed output nor memory usage
    are changed by this setting.  A work factor of 0 instructs the bzip library to use
    an internal default.   

    The <code class="literal">bzip2.decompress</code> filter only accepts one parameter,
    which can be passed as either an ordinary boolean value, or as the 
    <code class="parameter">small</code> element of an associative array.

    <code class="parameter">small</code>, when set to a <strong><code><a href="reserved.constants.php#constant.true">true</a></code></strong> value, instructs the bzip library
    to perform decompression in a minimal memory footprint at the cost of speed.
   </p>

   <p class="simpara">
     bzip2.* compression filters are available if
     <a href="ref.bzip2.php" class="link">bz2</a> support is enabled.
   </p>

   <div class="example" id="example-3">
    <p><strong>Example #3 
     <code class="literal">bzip2.compress</code> and
     <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">"The original file is " </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">" bytes long.\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">"The compressed file is " </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">" bytes long.\n"</span><span style="color: #007700">;

</span><span style="color: #FF8000">/* Generates output:

The original file is 3288 bytes long.
The compressed file is 1488 bytes long.

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

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