Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 1 of 1
  1. #1
    Senior Coder Dormilich's Avatar
    Join Date
    Jan 2010
    Location
    Behind the Wall
    Posts
    3,302
    Thanks
    13
    Thanked 345 Times in 341 Posts

    HTML Header Script

    This script is intended to ease the output of HTML headers (server and client side). Just define the type, language and encoding of the document and the script will take care of the (X)HTML output. There are additional features built in (deny to serve, custom XHTML), that may come in handy.

    PHP Code:
    <?php
    /*
     *      class.headers.php
     *      
     *      Copyright 2009 Alexander Stranzky <Dormilich@netscape.net>
     *      
     *      This program is free software; you can redistribute it and/or modify
     *      it under the terms of the GNU General Public License as published by
     *      the Free Software Foundation; either version 2 of the License, or
     *      (at your option) any later version.
     *      
     *      This program is distributed in the hope that it will be useful,
     *      but WITHOUT ANY WARRANTY; without even the implied warranty of
     *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     *      GNU General Public License for more details.
     *      
     *      You should have received a copy of the GNU General Public License
     *      along with this program; if not, write to the Free Software
     *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
     *      MA 02110-1301, USA.
     */

    ###########################################################
    # printing DOCTYPE, <HTML>, <HEAD>, <META "content-type"> #
    ###########################################################

    /**
     * Based on the Function by Dave Shea.
     *
     * due to IE's lack of support for "application/xhtml+xml" (XHTML 1.1
     * recommended MIME type) a browser switch (XHTML/HTML) is made. All
     * browsers accepting "application/xhtml+xml" will be served with the 
     * default output (which is currently XHTML 1.0) for all others the
     * output will be buffered and corrected towards HTML 4.01.
     *   XHTML Coders: empty elements that are not empty or don't have an
     * optional closing tag in HTML are thus likely to inflict problems.
     *
     * How to set the options
     * ======================
     * there are 5 options available:
     * - Document MIME type (HTML 4.01, HTML 5, XHTML 1.0, XHTML 1.1, XHTML)
     * - Document language
     * - Document encoding (character set)
     * - Script language MIME type
     * - Stylesheet MIME type (currently disabled)
     * - Denial to Serve (if the MIME type is not supported)
     *
     * of which the first 3 can be set using the class' constructor, but all
     * of them can be set later as they are public properties. Should you choose
     * to take the 'XHTML' MIME type, you need to set the DTD string beforehand.
     * This will be required, when you need to use 'mixed' XHTML types, such as
     * XHTML+SVG, XHTML+MathML, XHTML+RDFa, etc.
     *   You can choose to deny serving XHTML to User Agents (UA) that do not
     * support the set MIME type by setting $errorCode to a HTTP Client Error
     * Code (4xx). A denied document does not contain any data, so UA don't
     * display any message. However you can read the HTTP Response Headers. You
     * can forcibly deny a document by calling the deny() method.
     *   Note that XHTML 1.1 can only be served using "application/xhtml+xml".
     */
    class Headers
    {
        
    /**
         * @const (string) DTD_XHTML_10      XHTML 1.0 Strict DTD
         * @const (string) DTD_XHTML_11      XHTML 1.1 DTD
         * @const (string) DTD_HTML_401      HTML 4.01 Strict DTD
         * @const (string) DTD_HTML_5        HTML 5 DTD
         * @const (string) XMLNS_XHTML       XHTML namespace
         * @const (string) META_TYPE_CSS     meta element defining the default
         *                                   style MIME type
         * @const (string) META_TYPE_JS      meta element defining the default
         *                                   script MIME type
         * @const (string) MIME_TYPE_CSS     MIME type for CSS files
         * @const (string) MIME_TYPE_JS      MIME type for JavaScript files
         * @const (string) MIME_TYPE_XML     MIME type for XML text files
         * @const (string) MIME_TYPE_HTML    MIME type for HTML files
         * @const (string) MIME_TYPE_XHTML   MIME type for XHTML files
         * @var (array) HTTP_ERROR_MSG       HTTP Error Codes 4xx series (RFC 2616)
         * @var (string) $mime               default page MIME type
         * @var (string) $mime_js            JavaScript MIME type (changeable)
         * @var (string) $mime_css           CSS MIME type (changeable)
         * @var (string) $type               default page type ((X)HTML),
         *                                   may be edited by the user
         * @var (string) $encoding           page encoding/charset, 
         *                                   may be edited by the user
         * @var (string) $language           default page language,
         *                                   may be edited by the user
         * @var (string) $dtd                used for a custom DTD
         * @var (mixed) $errorCode           HTTP Error Code to send or false
         *                                   for XHTML -> HTML conversion
         */
        
    const DTD_XHTML_10    '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
        const 
    DTD_XHTML_11    '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
        const 
    DTD_HTML_401    '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">';
        const 
    DTD_HTML_5      '<!DOCTYPE html>';

        const 
    XMLNS_XHTML      'xmlns="http://www.w3.org/1999/xhtml"';

        const 
    META_TYPE_CSS   '<meta http-equiv="content-style-type" content="text/css"/>';
        const 
    META_TYPE_JS    '<meta http-equiv="content-script-type" content="%s"/>';
        const 
    MIME_TYPE_JS    'text/javascript';
        const 
    MIME_TYPE_CSS   'text/css';
        const 
    MIME_TYPE_XML      'text/xml';
        const 
    MIME_TYPE_HTML  'text/html';
        const 
    MIME_TYPE_XHTML 'application/xhtml+xml';
        
        protected static 
    $HTTP_ERROR_MSG = array(
            
    400 => "Bad Request",
            
    401 => "Unauthorized",
            
    402 => "Payment Required",
            
    403 => "Forbidden",
            
    404 => "Not Found",
            
    405 => "Method Not Allowed",
            
    406 => "Not Acceptable",
            
    407 => "Proxy Authentication Required",
            
    408 => "Request Timeout",
            
    409 => "Conflict",
            
    410 => "Gone",
            
    411 => "Length Required",
            
    412 => "Precondition Failed",
            
    413 => "Request Entity Too Large",
            
    414 => "Request-URI Too Long",
            
    415 => "Unsupported Media Type",
            
    416 => "Requested Range Not Satisfiable",
            
    417 => "Expectation Failed"
        
    );

        public 
    $mime          'text/html';
        public 
    $mime_js       'text/javascript';
    /*
        'text/ecmascript'
        'application/javascript'
        'application/ecmascript'
    */
        
    public $mime_css      'text/css';
        public 
    $type          'XHTML 1.0';
        public 
    $encoding      'UTF-8';
        public 
    $language      'de';
        public 
    $dtd           '';
        public 
    $errorCode     false;
        
        
    /**
         * determine the supported MIME type. set defaults.
         *
         * @param (string) $encoding   encoding/charset of the document [UTF-8]
         * @param (string) $lang       used language [de]
         * @param (string) $type       used DTD/HTML version [XHTML 1.1]
         * @return (void)
         */
        
    public function __construct(
            
    $encoding 'UTF-8',
            
    $lang     'de',
            
    $type     'XHTML 1.0'
        
    )
        {
            
    $this->type     $type;
            
    $this->encoding $encoding;
            
    $this->language $lang;
            
    # set defaults
            
    $this->mime_css self::MIME_TYPE_CSS;
            
    $this->mime_js  self::MIME_TYPE_JS;
            
    # determine possible MIME type for XHTML
            
    $this->changeMIME();
            
    $this->specialUA();
        }
        
        
    /**
         * setter method for the encoding/charset property.
         *
         * @return (Headers)           instance for chaining
         */
        
    public function setEncoding(
            
    $charset 'UTF-8'
        
    )
        {
            
    $this->encoding $charset;
            return 
    $this;
        }
        
        
    /**
         * setter method for language property.
         *
         * @return (Headers)           instance for chaining
         */
        
    public function setLanguage(
            
    $lang 'de'
        
    )
        {
            
    $this->language $lang;
            return 
    $this;
        }
        
        
    /**
         * setter method for Doctype identifyer.
         *
         * @return (Headers)           instance for chaining
         */
        
    public function setDocType(
            
    $type 'XHTML 1.0'
        
    )
        {
            
    $this->type strtoupper($type);
            return 
    $this;
        }

        
    /**
         * Send a HTTP Status Code of the 4xx series (Client Errors) to the client.
         *
         * @param (int) $code          HTTP Error Code Number
         * @throws (CodeException)     not a Client Error Code
         */
        
    public function deny(
            
    $code 406
        
    )
        {
            if (!isset(
    self::$HTTP_ERROR_MSG[$code]))
            {
                
    $emsg "Only Client Error HTTP Status Codes supported.";
                throw new 
    Exception($emsg);
            }
            
    header("HTTP/1.1 $code " self::$HTTP_ERROR_MSG[$code]);
            
    header("Status: $code "  self::$HTTP_ERROR_MSG[$code]);
            
    header("Connection: Close");
            exit;
        }
        
        
    /**
         * send PHP headers and print the (X)HTML headers. if MIME type is set to
         * HTML, start the output correction (XHTML -> HTML) via output buffer.
         *
         * @return (string)            HTML headers
         */
        
    public function __toString()
        {
            
    # reset MIME type for HTML documents
            
    if ('HTML 4.01' == $this->type)
            {
                
    $this->mime self::MIME_TYPE_HTML;
                
    # otherwise leave it at XHTML
            
    }
            
    # convenience variable
            
    $_isXHTML is_int(strpos($this->type'XHTML'));
            
            
    # don't serve XHTML 1.1 to UAs that don't know "application/xhtml+xml"
            
    if ('XHTML 1.1' == $this->type and self::MIME_TYPE_XHTML != $this->mime)
            {
                
    $this->deny(406);
            }
            
    # forcibly don't serve XHTML to UAs that don't know "application/xhtml+xml"
            
    if ($_isXHTML and self::MIME_TYPE_XHTML != $this->mime and is_int($this->errorCode))
            {
                
    $this->deny($this->errorCode);
            }
            
    # remove empty xml tag notation ("/>" -> ">")
            
    if ($_isXHTML and self::MIME_TYPE_HTML == $this->mime)
            {
                
    ob_start(array($this"fix_code"));
            }
            
    # send headers
            
    header("Content-Type: " $this->mime ";charset=" $this->encoding);
            
    header("Vary: Accept");

            
    # choose page type from MIME type
            
    if (self::MIME_TYPE_HTML == $this->mime)
            {
                
    $type 'HTML 4.01';
            }
            else
            {
                
    $type $this->type;
            }
            return 
    $this->getHeader($type);
        }
        
        
    /**
         * read the q-value (MIME type weighting) from HTTP_ACCEPT and set
         * the according MIME type. if support for XHTML is detected, change
         * the MIME type from HTML (default) to XHTML.
         *
         * @return (void)
         */
        
    protected function changeMIME()
        {
            
    $preg_xhtml "@application/xhtml\+xml;q=0(\.[1-9]+)@i";
            
    $preg_html  "@text/html;q=0(\.[1-9]+)@i";
            
            
    # close connection for non-browsers (no Accept header)
            
    if (!isset($_SERVER["HTTP_ACCEPT"]))
            {
                
    $this->deny(406);
            }
            
        
    //    $this->mime = self::MIME_TYPE_HTML;
            
            // change
            # match without q-value
            
    if (stristr($_SERVER["HTTP_ACCEPT"], self::MIME_TYPE_XHTML)) 
            {
                
    # match with q-value
                
    if (preg_match($preg_xhtml$_SERVER["HTTP_ACCEPT"], $matches)) 
                {
                    
    # compare html/xhtml from q-value
                    
    $xhtml_q $matches[1];
                    if (
    preg_match($preg_html$_SERVER["HTTP_ACCEPT"], $matches)) 
                    {
                        
    $html_q $matches[1];
                        if (
    $xhtml_q >= $html_q
                        {
                            
    $this->mime self::MIME_TYPE_XHTML;
                        }
                    }
                }
                else 
                {
                    
    $this->mime self::MIME_TYPE_XHTML;
                }
            }
        }
        
        
    /**
         * correct the MIME type for some special User Agents that are not
         * correctly recognized by self::changeMIME() or which contain bugs
         * that would lead to errors.
         *
         * @return (bool)              HTTP_USER_AGENT available
         */
        
    protected function specialUA()
        {
            if (!isset(
    $_SERVER["HTTP_USER_AGENT"]))
            {
                return 
    false;
            }
            
    # special check for the W3C_Validator
            
    if (stristr($_SERVER["HTTP_USER_AGENT"], "W3C_Validator")) 
            {
                
    $this->mime self::MIME_TYPE_XHTML;
            }
            
    # special check for Shiira
            
    if (stristr($_SERVER["HTTP_USER_AGENT"], "Shiira")) 
            {
                
    $this->mime self::MIME_TYPE_HTML;
            }
            return 
    true;
        }
        
        
    /**
         * build the headers (from XML Prolog to <meta>s) according to the
         * set MIME type. 
         *
         * @param (string) $type       MIME type
         * @return (string)               headers formatted for printing
         */
        
    public function getHeader(
            
    $type 'XHTML'
        
    )
        {
            
    # XML Prolog
            
    $xml '<?xml version="1.0" encoding="' $this->encoding "\" ?>\n";
            
    $meta '
        <head>
            <meta http-equiv="content-type" content="' 
    $this->mime ';charset=' $this->encoding '"/>';
            
            switch (
    $type)
            {
                case 
    'XHTML 1.1':
                    
    # DTD
                    
    $dtd  self::DTD_XHTML_11 "\n";
                    
    # <html>
                    
    $html '<html ' 
                          
    self::XMLNS_XHTML 
                          
    ' xml:lang="' $this->language '">';
                    break;

                case 
    'XHTML 1.0':
                    
    # DTD
                    
    $dtd  self::DTD_XHTML_10 "\n";
                    
    # <html>
                    
    $html '<html ' 
                          
    self::XMLNS_XHTML 
                          
    ' xml:lang="' $this->language '"'
                          
    ' lang="' $this->language '">';
                    break;

                
    // XHTML special types like XHTML+SVG, XHTML+MathML, etc.
                
    case 'XHTML'
                    
    # DTD
                    
    $dtd $this->dtd;
                    
    # <html>
                    
    $html '<html ' 
                          
    self::XMLNS_XHTML 
                          
    ' xml:lang="' $this->language '">';
                    break;
                
                case 
    'XHTML 5':
                    
    # DTD
                    
    $dtd self::DTD_HTML_5 "\n";;
                    
    # <html>
                    
    $html '<html ' 
                          
    self::XMLNS_XHTML 
                          
    ' xml:lang="' $this->language '">';
                    break;
                
                case 
    'HTML 5':
                    
    # no XML prolog
                    
    $xml '';
                    
    # DTD
                    
    $dtd self::DTD_HTML_5 "\n";;
                    
    # <html>
                    
    $html '<html lang="' $this->language '">';
                    break;
                
                case 
    'HTML 4.01':
                default:
                    
    # no XML prolog
                    
    $xml '';
                    
    # DTD
                    
    $dtd  self::DTD_HTML_401 "\n";
                    
    # <html>
                    
    $html '<html lang="' $this->language '">';
                    
    # <meta>
                    
    break;
            }
            
            
    $header $xml $dtd $html $meta 
                    
    "\n\t\t" self::META_TYPE_CSS 
                    
    "\n\t\t" sprintf(self::META_TYPE_JS,  $this->mime_js);
            return 
    $header;
        }

        
    /**
         * convert XHTML to HTML (basicly treating the empty elements)
         *
         * @param (string) $buffer     content from the output buffer
         * @return (string)               HTML code to send to the browser
         */
        
    public function fix_code($buffer
        {
            return (
    str_replace("/>"">"$buffer));
        }
    }     
    ?>
    example usage:
    PHP Code:
    <?php
    echo new Headers("ISO-8859-1""en");
    ?>

    // output IE
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html lang="en">
        <head>
            <meta http-equiv="content-type" content="text/html;charset=ISO-8859-1">
            <meta http-equiv="content-style-type" content="text/css">
            <meta http-equiv="content-script-type" content="text/javascript">

    // output other browsers
    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
        <head>
            <meta http-equiv="content-type" content="application/xhtml+xml;charset=ISO-8859-1"/>
            <meta http-equiv="content-style-type" content="text/css"/>
            <meta http-equiv="content-script-type" content="text/javascript"/>
    PHP Code:
    <?php
    $h 
    = new Headers;
    $h->setDocType("XHTML 1.1")
      ->
    mime_js "application/ecmascript";
    echo 
    $h;
    ?>
    // output IE

    // output other browsers
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
        <head>
            <meta http-equiv="content-type" content="application/xhtml+xml;charset=UTF-8"/>
            <meta http-equiv="content-style-type" content="text/css"/>
            <meta http-equiv="content-script-type" content="application/ecmascript"/>
    Note on the attached file: this script uses a custom Exception for better Error Handling, thus change line #218 apropriately.
    Attached Files Attached Files
    Last edited by Dormilich; 01-19-2010 at 10:43 AM.


 

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •