Home arrow PHP arrow Page 4 - Building Object-oriented Web Pages with HTTP Compression in PHP

Putting the pieces together: compressing the output of a web page generator class - PHP

Here we go! Welcome to the third -– and last -- part of the series “Using HTTP compression in PHP.” Just in case you didn’t know, this set of tutorials explores the advantages of using HTTP compression on dynamic PHP pages, reducing their download times and increasing the overall performance of PHP applications.

TABLE OF CONTENTS:
  1. Building Object-oriented Web Pages with HTTP Compression in PHP
  2. Object-based web pages in a nutshell: defining (X)HTML widget classes
  3. More web page objects ahead: defining the remaining (X)HTML widget classes
  4. Putting the pieces together: compressing the output of a web page generator class
By: Alejandro Gervasio
Rating: starstarstarstarstar / 5
April 24, 2006

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

One of the best things about PHP is the way it allows you to develop different mechanisms, focused on speeding up the performance of certain applications. This is especially applicable when working with object-oriented web pages, since the page rendering process demands the instantiation of numerous objects which must coexist with each other, at least until the page has been completely assembled on the server.

Considering the eventual issues of working with various objects that might affect the performance of the entire application, reducing the amount of data transferred from the server to the client is something that can be easily achieved with HTTP compression. In this particular case, first I’ll define an object factory class, tasked with creating and returning web page objects; then I'll create a page generator class, which will use “Gzip” encoding to compress the dynamic output of object-based web documents.

Here’s the signature of these two classes, so have a look at them:

// abstract 'ObjectFactory' class
abstract class ObjectFactory{
    private function __construct(){}
    public function createObject($type,$attributes=array()){
        if(!class_exists($type)||!is_array($attributes)){
            throw new Exception('Invalid object parameters');
        }
        return new $type($attributes);
    }
}
// 'PageGenerator' class
class PageGenerator{
    private $output;
    private $title;
    private $keywords;
    private $cssFile;
    private $jsFile;
    public function __construct(){
        $this->output='';
        $this->title='Sample Page';
        $this->keywords='PHP,OOP,Output buffering,HTTP
Compression';
        $this->cssFile='styles.css';
        $this->jsFile='global_functions.js';
    }
    public function setTitle($title){
        $this->title=$title;
    }
    public function setKeywords($keywords){
        $this->keywords=$keywords;
    }
    public function setCssFile($cssFile){
        $this->cssFile=$cssFile;
    }
    public function setJsFile($jsFile){
        $this->jsFile=$jsFile;
    }
    public function makeHeader(){
        $this->output='<html><head><title>'.$this-
>title.'</title><meta name="keywords" content="'.$this-
>keywords.'" /><link rel="stylesheet" href="'.$this->cssFile.'"
type="text/css"><script language="javascript" src="'.$this-
>jsFile.'"></script></head><body>';
    }
    public function addHTMLElement(HTMLElement $htmlElement){
        $this->output.=$htmlElement->getHTML();
    }
    public function makeFooter(){
        $this->output.='</body></html>';
    }
    public function getHTML(){
        return $this->output;
    }
    public function getCompressedHTML(){
        // check if browser supports gzip encoding
        if(strstr($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip')){
            // start output buffer
            ob_start();
            // echo page contents to output buffer
            echo $this->getHTML();
            // crunch (X)HTML content & compress it with gzip
            $compHTML=gzencode(preg_replace("/
(rn|n)/","",ob_get_contents()),9);
            // clean up output buffer
            ob_end_clean();
            // return compressed (X)HTML content
            return $compHTML;
        }
        return false;
    }
    public function sendEncodingHeader(){
        header('Content-Encoding: gzip');
    }
}

As shown above, the first “Object Factory” class accepts two arguments: the type of web page object being created, along with its corresponding attributes. This means that if all goes well, the new object is returned to client code. As you can see, this class uses the factory design pattern for instantiating web page objects, thus if you’ve used this pattern before, you should have no problems applying it.

The second class, that is “PageGenerator,” is the most interesting one. It’s responsible for building up web pages, using input objects of type “HTMLElement,” which are passed on to its “addHTMLElement()” method. However, aside from creating the web document in question, this class exposes two additional methods, handy for compressing the corresponding (X)HTML output: “getCompressedHTML()” and “sendEncodingHeader()” respectively.

The first method uses the “gzencode()” function, in order to compress the web page’s output after fetching the contents from an output buffer. Then the compressed data is returned to the point from which this method is called. Additionally, the second method, “sendEncodingHeader(),” simply sends out the appropriate HTTP header, in order to indicate to the browser that data will be sent as “gzip-encoded” content.

At this stage, you hopefully understand how the above classes work together. Now, look at the following example, which illustrates the entire process for rendering and encoding the contents of a web page:

try{
    // instantiate some (X)HTML widget objects
    $h1=ObjectFactory::createObject('Header1',array
('class'=>'header1'));
    $h1->setData('This is a H1 header');
    $h2=ObjectFactory::createObject('Header2',array
('class'=>'header2'));
    $h2->setData('This is a H2 header');
    $h3=ObjectFactory::createObject('Header3',array
('class'=>'header3'));
    $h3->setData('This is a H3 header');
    $h4=ObjectFactory::createObject('Header4',array
('class'=>'header4'));
    $h4->setData('This is a H4 header');
    $h5=ObjectFactory::createObject('Header5',array
('class'=>'header5'));
    $h5->setData('This is a H5 header');
    $div=ObjectFactory::createObject('Div',array
('id'=>'content','class'=>'divclass'));
    $div->setData('Div content goes here');
    $par=ObjectFactory::createObject('Paragraph',array
('class'=>'paragraph'));
    $table=ObjectFactory::createObject('Table',array
('width'=>'500','class'=>'tableclass'));
    $table->setData(array('content'=>'Table content goes here'));
    $form=ObjectFactory::createObject('Form',array
('action'=>'formprocessor.php','method'=>'post'));
    $form->setData('Please enter your data below<br />');
    // add form fields
    $form->addInputField(array
('type'=>'text','name'=>'fname','size'=>'30'),'First Name');
    $form->addInputField(array
('type'=>'text','name'=>'lname','size'=>'30'),'<br />Last Name');
    $form->addInputField(array
('type'=>'text','name'=>'email','size'=>'30'),'<br />Email');
    $form->addTextArea(array
('name'=>'comments','rows'=>'20','cols'=>'30'),'<br />');
    $form->addSelectField(array('name'=>'options'),array
('value1'=>'1','value2'=>'2','value3'=>'3'),'<br />');
    $form->addInputField(array
('type'=>'submit','name'=>'send','value'=>'Send
Data'),'<br /><br />');
    // instantiate a new PageGenerator object
    $pageGen=new PageGenerator();
    // build web page header
    $pageGen->makeHeader();
    // add 'HTMLElement' objects
    $pageGen->addHTMLElement($h1);
    $pageGen->addHTMLElement($h2);
    $pageGen->addHTMLElement($h3);
    $pageGen->addHTMLElement($h4);
    $pageGen->addHTMLElement($h5);
    $pageGen->addHTMLElement($par);
    $pageGen->addHTMLElement($table);
    $pageGen->addHTMLElement($div);
    $pageGen->addHTMLElement($form);
    // build web page footer
    $pageGen->makeFooter();
    // send HTTP gzip encoding header
    $pageGen->sendEncodingHeader();
    // display compressed web page
    echo $pageGen->getCompressedHTML();
}
catch(Exception $e){
    echo $e->getMessage();
    exit();
}

As shown above, a basic web page is populated with a few (X)HTML objects, including a bunch of headers, a Div, a paragraph, and finally a simple web form. After these elements have been added by the corresponding “addHTMLElement()” method, the web document is generated on the server and then compressed. At the end of the script, web page contents are uncompressed in the client, after calling the proper “sendEncodingHeader()” method.

As you’ve seen, using HTTP compression within an object-based PHP application is a straightforward process, and certainly doesn’t require much effort from us to code a class that takes advantage of its benefits.

Of course, before compressing dynamic output, you should evaluate carefully if this is really worthwhile, since the benefits that you can obtain in the end will vary, depending of the nature and size of the data being compressed. In all these cases, a detailed benchmarking of a specific PHP application can help a lot in deciding when and how to implement HTTP compression.

Summary

Now this series is concluded. Over the different articles, I hope you learned several approaches for using HTTP compression in PHP, in order to decrease the download times of dynamic pages, and consequently reduce the amount of data transferred from the server to the client.

The numerous code samples that you saw here covered both procedural and object-based applications, and hopefully will serve as an instructive experience from which to develop more complex scripts that utilize HTTP compression. Now that you have the required knowledge, go ahead and empower your dynamic PHP applications with HTTP compression. Meet you in the next PHP tutorial!



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: