HomePHP Page 2 - An Object-based Approach to HTTP Compression in PHP
Object-based "Gzip" compression: creating a data compressor PHP class - PHP
Welcome to the second tutorial of the series “Using HTTP compression in PHP.” In three parts, this series demonstrates how to apply HTTP compression to parsed PHP pages, in order to reduce their overall download times, which results in faster delivery of dynamic content.
Before I make a data compressor class that internally uses "Gzip" encoding for compressing the data passed as input argument, first let me list the "getCompressedContent()" function that I wrote in the previous tutorial, to refresh your memory of how this function looked. Here is its signature:
function getCompressedContent($data){ // check if browser supports gzip encoding if(strstr($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip')){ // start output buffer ob_start(); // check to see if $data is a file if(file_exists($data)){ // include file into output buffer include($data); } else{ // echo string to output buffer echo $data; } // crunch content & compress data with gzip $data=gzencode(preg_replace("/ (rn|n)/","",ob_get_contents()),9); echo 'Hello'; // clean up output buffer ob_end_clean(); // send http header header('Content-Encoding: gzip'); } // return data return $data; }
Now, I hope the above function is pretty familiar to you, because I'm going to use it as the foundation for building the data compressor class that I mentioned before. Particularly, I'll define this class for use in PHP 5, but you can easily adapt its source code to include it within your PHP 4 scripts. Here's how the "DataCompressor" class looks:
// define 'DataCompressor' class class DataCompressor{ private $data; public function __construct($data){ if(!file_exists($data)||!is_string($data)){ throw new Exception('Invalid input data'); } $this->data=$data; } public function fetchCompressedData(){ // check if browser supports gzip encoding if(strstr($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip')){ // start output buffer ob_start(); // check to see if $data is a file if(file_exists($this->data)){ // include file into output buffer include($this->data); } else{ // echo string to output buffer echo $this->data; } // crunch content & compress data with gzip $this->data=gzencode(preg_replace("/ (rn|n)/",'',ob_get_contents()),9); // clean up output buffer ob_end_clean(); // return data return $this->data; } return false; } public function sendEncodingHeader(){ header('Content-Encoding: gzip'); } }
As I said earlier, I wrote the above class inspired by the source code of the previous "getCompressedContent()" function, something that should be quite obvious. As you can see, the workhorse of the class is the "fetchCompressedData()" method, which is very similar to its procedural counterpart. In this case, this method opens up an output buffer, then includes the contents of the $this->data property, and finally returns the "gzip-encoded" data, after cleaning up the respective buffer.
Additionally, the class constructor accepts the mentioned $data incoming argument, which is properly checked inside this method to make sure it's either a file or a simple string. Any other type of data passed on to the constructor will throw an exception, which eventually will be caught by client code.
Finally, I decided to define separately the "sendEncodingHeader()" method, providing the class with the ability to send this HTTP header when the method is specifically called. Definitely, breaking down the class code into different specific methods helps keep the whole class as a much more flexible programming structure.
Right, now that I've shown you the signature of the "DataCompressor" class, you'll probably want to see how it can be used within a basic sample PHP script. For this reason, jump into the next section, so you can learn how this class is utilized as part of a pretty useful hands-on example.