[php] Compression | Output Buffer control

Status
Not open for further replies.

litewarez

Active Member
1,367
2008
1
0
Heya guys, I just built this small tool so you can add into your sites to compress your content and and modify it to save bandwidth.

How it works:
This class will watch your script so when your echoing content it will do some modifications and can also take your own modifications aswell

The Class:
PHP:
<?php
class OutputBuffer
{
	private $callbacks = array(); //Holder for callbacks
	private $content;
	
	function __construct()
	{
		ob_start(array($this,'handler'));
	}
	
	function addCallback($name,$item)
	{
		if(is_callable($item))
		{
			$this->callbacks[$name] = $item;
			return true;
		}
		return false;
	}
	
	function handler($contents,$bitAtchion = null)
	{
		if($bitAtchion & PHP_OUTPUT_HANDLER_START)
		{
			$this->content = ''; //A New Buffer
		}
		
		if($bitAtchion & PHP_OUTPUT_HANDLER_CONT)
		{
			$this->content .= $contents;
		}
		
		if($bitAtchion & PHP_OUTPUT_HANDLER_END)
		{
			$this->content .= $contents;
			//AS this is a final request we want to run the callbacks
			foreach($this->callbacks as $this->callback)
			{
				try
				{
					$this->content = call_user_func($this->callback,$this->content);
				} catch(Exception $e){}
			}
			return $this->_compress($this->content); //Compress and push out
		}
		return $this->content;
	}
	
	function _compress($string)
	{
		if(headers_sent() || function_exists('gzencode') === false)
		{
			return $string; //Cant compress
		}
		
		$ctype = strpos($_SERVER["HTTP_ACCEPT_ENCODING"], 'x-gzip') ? 'x-gzip' : strpos($_SERVER["HTTP_ACCEPT_ENCODING"], 'gzip') ? 'gzip' : false;
		
		if($ctype !== false)
		{
			 header('Content-Encoding: '.$ctype);
			 return gzencode($string);
		}
		
		return $string;
	}
}
?>

Usage:
If you already have the function ob_start() in your script then replace with the code below, otherwise add the code below before your session_start() or at the very start of your script.

PHP:
include 'OutputBuffer.php';
$buffer = new OutputBuffer();

This will now compress your source before it gets to the user.

Adding Callbacks:
You can add your own custom callbacks to modify the end content such as rudes whitespace, add timestamps etc etc.

Example of callback:
PHP:
function addTimeStamp($content)
{
	return $content . '<!--' . time() . '-->';
}

As you can see the above is a function that returns the in-putted string but adds a html comment to the end with the time-stamp within it.

You can add it to your Output Controller like so:

PHP:
$buffer->addCallback('timestamp','addTimeStamp');

the params for the addCallback method are
Code:
addCallback( string $name[, mixed $callback]])

You can also add methods from objects by passing an array of the object adn the method

Example:

PHP:
$buffer->addCallback('tidyHtml',array($object,'method'));

heres another example that you can use to compress whitespace in your html source.

PHP:
function _trimwhitespace($source)
{
    // Pull out the script blocks
    preg_match_all("!<script[^>]*?>.*?</script>!is", $source, $match);
    $_script_blocks = $match[0];
    $source = preg_replace("!<script[^>]*?>.*?</script>!is",'@@@FILTER_TRIM_SCRIPT@@@', $source);

    // Pull out the pre blocks
    preg_match_all("!<pre[^>]*?>.*?</pre>!is", $source, $match);
    $_pre_blocks = $match[0];
    $source = preg_replace("!<pre[^>]*?>.*?</pre>!is",'@@@FILTER_TRIM_PRE@@@', $source);
    
    // Pull out the textarea blocks
    preg_match_all("!<textarea[^>]*?>.*?</textarea>!is", $source, $match);
    $_textarea_blocks = $match[0];
    $source = preg_replace("!<textarea[^>]*?>.*?</textarea>!is",'@@@FILTER_TRIM_TEXTAREA@@@', $source);

    // remove all leading spaces, tabs and carriage returns NOT
    // preceeded by a php close tag.
    $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source));

    // replace textarea blocks
    _outputfilter_trimwhitespace_replace("@@@FILTER_TRIM_TEXTAREA@@@",$_textarea_blocks, $source);

    // replace pre blocks
    _outputfilter_trimwhitespace_replace("@@@FILTER_TRIM_PRE@@@",$_pre_blocks, $source);

    // replace script blocks
    _outputfilter_trimwhitespace_replace("@@@FILTER_TRIM_SCRIPT@@@",$_script_blocks, $source);

    return $source;
}

//HELPER FUNCTION, NEEDED ABOVE.
function _outputfilter_trimwhitespace_replace($search_str, $replace, &$subject)
{
    $_len = strlen($search_str);
    $_pos = 0;
    for ($_i=0, $_count=count($replace); $_i<$_count; $_i++)
        if (($_pos=strpos($subject, $search_str, $_pos))!==false)
            $subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
        else
            break;
}

and then you can just keep this in a seperate file and include it and then add the callback like so

PHP:
$buffer->addCallback('trim_white_space','_trimwhitespace');

this will change the following code:
Code:
<html>
    <head>
        <title>my Website</title>
    </head>
    <body>
       <p>.....</p>
    </body>
</html>

Into:
Code:
<html><head><title>my Website</title></head><body><p>.....</p></body></html>
Now all your html will be compress like Litewarez and Katz.

P.S, The above function was taken from a smarty plugin and slightly modified
 
2 comments
Status
Not open for further replies.
Back
Top