Conteg v0.13 - Content Negotiation + Cache-Control for PHP-originated Web Output.
Basic Implementation
------------------
Introduction
------------
Conteg utilises the content-negotiation features of the HTTP protocol to:
* Reduce bandwidth
* Increase perceived (and actual) server responsiveness
The requirements are:
* PHP 4.1.0+
* zlib (for compression - odds are you have it)
* `ExtendedStatus On' in httpd.conf (Apache) (re: $_SERVER-type variables)
With the appropriate switches, Conteg will auto-send the correct:
* 304 Not Modified
* 406 Not Acceptable
* 412 Precondition Failed
* 416 Requested Range Not Satisfiable
* 206 Partial content, or
* 200 OK page
+ full headers
(404 + arbitrary status headers also available)
The simplest possible usage requires 3 lines of code and, by default, will:
* Auto-negotiate load-balanced compression
- Accept-Encoding negotiation accommodates known browser foibles
- load-balancing currently works on Linux, FreeBSD only
* Auto-switch according to HTTP protocol version
* Send Content-Type, Charset, Content-Language + Expiry Response headers
- by default, 'text/html', 'ISO-8859-1', 'en' + 3600
* Send Cache-Control headers to ensure full caching of content
* Report Referer, Browser + OS-platform
* Report a full range of Request headers
Implementation - One-Time Config
--------------------------------
Before use: locate `$_num_cpu' and change to the number on *your* machine (default 1).
Implementation - Simplest
-------------------------
The following is copied from comments included with the Class:
* How to use:
*
* Simplest possible usage requires 3 lines:
* 1 Turn Output Buffering on.
* 2 Include the Class file.
* 3 On the *very* last line create an instance of the Class.
*
* ------------Start of file---------------
* |<?php
* | ob_start(); // <==== line 1
* | include('Conteg.inc'); // <==== line 2
* |
* |... the page ...
* |
* | new Conteg(); // <==== line 3
* |?>
* -------------End of file----------------
*
* Things to note:
* 1 The '<?php' tag MUST be the first characters of the file
* 2 Likewise, the '?>' tag MUST be the final characters of the file.
* +Be careful of a space hiding there.
* 3 Output buffering can be turned on in the main config file, in which
* +case line 1 above is optional.
* 4 An auto_prepend_file is a possibility for `ob_start()' and an
* +auto_append_file for `new Conteg()'.
If the defaults ('text/html', 'ISO-8859-1', 'en' + Expiry: 3600) are unsuitable for your site,
it will be necessary to either change them within the Class, or to move to the next usage level.
Implementation - Next Level
---------------------------
Here, either the supplied defaults are unsuitable or--more likely with any non-trivial usage
of the Class--the headers supplied for a specific page are anticipated to vary. The most obvious
(and important) example is the `Last-Modified' header - see below.
An array is available as a setup parameter to both the Class constructor (line 3 above) and
`setup()' function. It is an array of `parameter-name' => `parameter-value' pairs.
The overview is to:
1 Instantiate the Class early
- setup common-page defaults using the setup parameter
- include `no-print = TRUE' (default is `FALSE': print-on-declaration)
2 Switch the Class defaults using `setup()' as required
- may be done at any time before send-page, and more than once
3 At program end, use `show()' to send the page
The following pseudo-PHP will assume that `$mdate' is set to the page modified-date.
<?php
ob_start(); // Conteg requirement
error_reporting( E_ALL ); // this is a test file
include( 'Conteg.include' );
$param = array(
'noprint' => TRUE, // default is show immediate
'expiry' => 864000 // set expiry date 10 days from now for all pages
); //+ default is 1 hour
$_Instance = new Conteg( $param );
...
(normal program flow)
...
// page-send
$param = array(
'modified' => strtotime( $mdate ) // ($mdate is string) default is time()
);
$_Instance->setup( $param );
$_Instance->show();
// any prog cleanup or processing goes here
// careful not to cause any more output
?>
These are the most likely parameter values to be used (with defaults)
(a full list of 31 is included within the Class comments):
Accept-Encoding (load-balanced compression):
'encodings' => array( 'gzip','deflate','compress' ),
'use_accept_encode' => TRUE,
Last-Modified, Expiry + Cache-Control:
'expiry' => 3600, // secs after time()
'modified' => NULL, // sets $last_modified to time()
'cache_control' => array( 'macro' => 'cache-all' ), // many other values available
// 'cache_control' => array( 'macro' => 'cache-none' ),
Charset, Language + Media-Type
(Note that, by default, these are reported but are NOT auto-negotiated):
'charset' => 'ISO-8859-1',
'lang' => 'en',
'type' => 'text/html',
'use_accept' => FALSE,
'use_accept_charset' => FALSE,
'use_accept_lang' => FALSE,
'use_content_lang' => TRUE,
'use_content_type' => TRUE,
ETag, Ranges
(off by default; see also below):
'etag' => '', // external (strong) ETag
'other_var' => '', // extra string to affect (weak) ETag
'use_accept_ranges' => FALSE,
'use_etag' => FALSE, // both strong + weak OFF by default
'weak_etag' => TRUE
A Note on ETags
---------------
Strong ETags allow the use of `Accept-Range' (auto-negotiation of `If-None-Match', `If-Match',
`If-Range' + `Range'). Weak ETags allow auto-negotiation of `If-None-Match' + `If-Match'. The Class
default is for Weak ETags, since these are more commonly suitable for dynamic pages and content.
The following is from comments included with the Class:
* Strong ETags: 2 pages with the same ETag are byte-by-byte the same
* Weak ETags: 2 pages with the same ETag are *essentially* the same.
*
* An example from modem-help.com is that the hit-counter, etc. may change,
* +but the rest of the content remains unchanged. If principal content changes
* +then the Modification Date is changed, which changes the (weak) ETag.
*
* For Strong ETags the Class md5's the content, which can be slow on extremely
* +large files. An external ETag can be provided for these cases.
'other_var': The Class MD5's the following parameters to obtain a weak ETag:
-----------
$this->_scriptName.
$this->_port.
$this->_query.
$this->_session.
$this->last_modified.
$this->content_type.
$this->content_lang.
$this->_charset.
$this->_other_var
(this is extremely quick).
`other_var' is a catch-all extra value to provide in those cases where some-other-feature(s)
of the page has changed, and to signal that to the User-Agent.
Some references
---------------
* HTTP/1.1: : http://www.w3.org/Protocols/rfc2616/rfc2616.html
* HTTP/1.0: : http://www.w3.org/Protocols/rfc1945/rfc1945.txt
* v0.13 release announcement : http://forums.modem-help.com/viewtopic.php?t=670
* v0.12.3 : http://forums.modem-help.com/viewtopic.php?t=603
* v0.12.2 : http://forums.modem-help.com/viewtopic.php?t=581
* v0.12.1 : http://forums.modem-help.com/viewtopic.php?t=568
* v0.10 : http://forums.modem-help.com/viewtopic.php?t=128
(c) Alex Kemp 28 February, 2007
website: http://www.modem-help.com/
(email address with-held due to historical/hysterical problems)
(contact instead via PM at http://forums.modem-help.com/)
|