Skip to content

xp-forge/compression

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

50 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Compression streams

Build status on GitHub XP Framework Module BSD Licence Requires PHP 7.0+ Supports PHP 8.0+ Latest Stable Version

Compressing output and decompressing input streams including GZip, BZip2 and Brotli.

Examples

Reading a GZIP-compressed file:

use io\streams\FileInputStream;
use io\streams\compress\GzipInputStream;

$in= new GzipInputStream(new FileInputStream('message.txt.gz'));
while ($in->available()) {
  echo $in->read();
}
$in->close();

Writing a file, compressing the data on-the-fly with BZIP2:

use io\streams\FileOutputStream;
use io\streams\compress\Bzip2OutputStream;

$out= new Bzip2OutputStream(new FileOutputStream('message.txt.bz2'));
$out->write('Hello World!');
$out->write("\n");
$out->close();

Dependencies

Compression algorithms are implemented in C and thus require a specific PHP extension:

Accessing these algorithms can be done via the Compression API:

use io\streams\{Compression, FileInputStream, FileOutputStream};

// Returns an algorithm instance. Raises a lang.MethodNotImplementedException
// if the required "bzip2" extension is not loaded
$compressed= Compression::named('bzip2');

// Read
$bytes= '';
$in= $compressed->open(new FileInputStream($file));
while ($in->available()) {
  $bytes.= $in->read();
}
$in->close();

// Write using strongest compression (other predefined values are FASTEST
// and DEFAULT; alternatively, the level can be passed directly).
$out= $compressed->create(new FileOutputStream($file), Compression::STRONGEST);
$out->write($bytes);
$out->close();

Discovering supported algorithms can be done using the Compression API:

use io\streams\Compression;

echo "Supported algorithms:\n";
foreach (Compression::algorithms()->supported() as $compression) {
  echo '✓ ', $compression->name(), "\n";
}

...or as a one-line shell command:

$ xp -w '\io\streams\Compression::algorithms()'
io.streams.compress.Algorithms@{
  io.streams.compress.Gzip(token: gzip, extension: .gz, supported: true, levels: 1..9)
  io.streams.compress.Bzip2(token: bzip2, extension: .bz2, supported: false, levels: 1..9)
  io.streams.compress.Brotli(token: br, extension: .br, supported: true, levels: 1..11)
}

Advanced example

Fetching a given URL using HTTP Accept-Encoding and Content-Encoding:

use io\streams\Compression;
use peer\http\HttpConnection;

// Compile list of supported compression algorithms, e.g. "gzip, br"
$accept= Compression::algorithms()->accept();
echo "== Sending {$accept} ==\n";

// Make request, sending supported content encodings via Accept-Encoding
$conn= new HttpConnection($argv[1]);
$res= $conn->get(null, ['Accept-Encoding' => $accept]);

// Handle Content-Encoding header
if ($encoding= $res->header('Content-Encoding')) {
  $compression= Compression::named($encoding[0]);

  echo "== Using ", $compression->name(), " ==\n";
  $in= $compression->open($res->in());
} else {
  echo "== Uncompressed ==\n";
  $in= $res->in();
}

// Write contents to output
while ($in->available()) {
  echo $in->read();
}
$in->close();