The code:
<?php
/*  xhtml-or-html.php
Author: Ben de Groot -- http://www.stijlstek.nl/
The code is not completely original, but based on various sources on the Internet
Version: 0.2 -- 30 September 2004

DESCRIPTION:
This code will question the browser requesting the document:
1. if it recognizes the XHTML mime-type
2. if so, does it prefer XHTML over HTML?
Accordingly, the correct headers will be sent with the appropriate doctype.
If needed the XHTML document will be translated into HTML. In the present form
it is presupposed that the document code is strict XHTML, so the choice will
be to send XHTML 1.1 or XHTML 1.0 Strict.

USAGE:
This code needs to be called at the very beginning of the document. Other PHP code 
may preceed this, as long as it doesn't output anything. Make sure no whitespace 
preceeds the PHP tag. This code will send headers and start the XHTML document. 
After this the document should resume with the head tag immediately.

USAGE EXAMPLE:
<?php
require_once('config.php');
require_once('xhtml-or-html.php');
?>
<head>

COPYRIGHT
Copyright (C) 2004 Ben de Groot

    This file is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This file 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this file; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

*/

// You can change the below default values
$charset = "UTF-8";   // when using XHTML, you really should use utf-8, but make sure your editor also outputs utf-8
$doclang = "en";      // the language your document is written in
$mime = "text/html";  // fall-back mime-type, IE needs text/html
$quirksmode = "<!-- let's put IE in quirks mode -->\n"; // putting IE6 in quirks mode is easier for stylesheets,
                                                        // change to "" to put IE6 in standards mode

// this function translates xhtml into html
function htmlize($buffer) {
    return (preg_replace("!\s*>!", ">", $buffer));
}

// we check the browser's accept-header to see if it prefers xhtml over html
if(stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml")) {
    if(preg_match("/application\/xhtml\+xml;q=0(\.[1-9]+)/i",$_SERVER["HTTP_ACCEPT"],$matches)) {
        $xhtml_q = $matches[1];
        if(preg_match("/text\/html;q=0(\.[1-9]+)/i",$_SERVER["HTTP_ACCEPT"],$matches)) {
            $html_q = $matches[1];
            if($xhtml_q >= $html_q) {
                $mime = "application/xhtml+xml";
            }
        }
    } else {
    $mime = "application/xhtml+xml";
    }
}

// the validators can handle xhtml but don't send the correct accept-headers
// you can comment this out if you want the validators to receive html instead of xhtml
if(stristr($_SERVER["HTTP_USER_AGENT"],"W3C_Validator")     ||
    stristr($_SERVER["HTTP_USER_AGENT"],"W3C_CSS_Validator") ||
    stristr($_SERVER["HTTP_USER_AGENT"],"WDG_Validator")) {
        $mime = "application/xhtml+xml";
}

// we choose the doctype that matches the mime-type
if($mime == "application/xhtml+xml") {
    $docstart = "<?xml version=\"1.0\" encoding=\"$charset\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"
        \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n
    <html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"$doclang\">\n";
} else {
    ob_start("htmlize");
    $docstart = "$quirksmode<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n
    <html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n";
}

// we send the correct headers and print the appropriate prolog, doctype and html opening tag
header("Content-Type: $mime;charset=$charset");
header("Vary: Accept");
print $docstart;

// because we already printed the html opening tag, the document that follows should open immediately with the head tag
?>