Blog » Content types, XHTML vs. HTML, and sniffing
- Posted: Dec 13th 2004, 17:41
There are a great deal of arguments going about proclaiming that XHTML shouldn’t be used. I believe it shouldn’t be used if you aren’t extending HTML. The reason that it is called extensible is because you may possibly want to add data to a page which isn’t available with simple markup. Jacques Distler uses XHTML with MathML to discuss a plethora of mind bloggling theorems, laws, and corollaries. Anne van Kesteren has discussed the creators of Opera having a desire to make a voice enabled browser, based upon the XHTML+Voice Profile, in his article titled: Multimodal Opera Browser. There are endless possibilities being created daily but what most people are doing is listening to all the snake oil
which Mark Pilgrim spoke about in one of his articles about semantics:
Semantic markup is independent of XHTML-vs-HTML (which makes sense, since there aren’t any new tags in XHTML that could provide new meaning). Semantic markup is independent of validation; you can produce shitty non-semantic markup that validates. Semantic markup and CSS are loosely joined, as described below.
I have totally wandered away from the purpose of this post, perhaps intentionally done in order to get my true opinions across. I wanted to show the function I knocked-up in order to give people some idea of how I, personally, browser sniff with my website. Ultimately, you should think about just using HTML in any web-site which you aren’t planning on extending.
function astristr($haystack='', $needle=array()) {
foreach($needle as $n) {
if (stristr($haystack, $n) !== false ) {
return true;
}
}
return false;
}
This initial function checks haystack for any string present within the needle array.
function sniff_header($acceptinput="",$array_pref_type="") {
$msiespoofs = array("opera"); //Ignore any spoofed user agent strings. Opera adds its name to the end of the spoof MSIE string
$acceptinput = $acceptinput!=""?$acceptinput:$_SERVER['HTTP_ACCEPT'];
$array_pref_type = is_array($array_pref_type)?$array_pref_type:array("application/xhtml+xml","text/html");//If you leave this string blank it uses the XHTML/HTML types. This function can be used to determine other content types (such as png and gif).
$vars_temp = explode(",",$acceptinput);
$calc_type = "";
$calc_level = 0;
foreach($vars_temp as $var) {
$splitvar = explode(";",$var);
$value = isset($splitvar[1])?(int) $splitvar[1]:1;
$contenttype = trim($splitvar[0]);
if(in_array($contenttype,$array_pref_type)) {
if( ($value > $calc_level) || ( ($value == $calc_level) && (array_search($contenttype,$array_pref_type) < array_search($calc_type,$array_pref_type))) ) {
$calc_type = $contenttype;
$calc_level = $value;
}
}
if($calc_type == "*/*" && ( (false===stristr($_SERVER['HTTP_USER_AGENT'],'msie')) or (astristr($_SERVER['HTTP_USER_AGENT'],$msiespoofs))) ) {//Serve your preference to all but MSIE
$calc_type = $array_pref_type[0];
$calc_level = 2;
}
}
if(in_array("text/html",$array_pref_type)) { //MSIE override - sends text/html if specified
$calc_type = (( (false!==stristr($_SERVER['HTTP_USER_AGENT'],'msie')) && (!astristr($_SERVER['HTTP_USER_AGENT'],$msiespoofs) )))?"text/html":$calc_type;
}
return $calc_type!=""?$calc_type:$array_pref_type[0];
}
The function loops through the accept types and compares them with the specified content types which you are willing to serve (array_pref_type). It checks and compares the weighting specified by the q value in order to give the best calculation. If / is given, it takes this into account and serves your preference. Of course MSIE gets a rougher deal and so it is given text/html in HTML situations.
Admittedly this is a more clumsy function than many I have seen but it is mine and I understand it. I was tempted to make it a little more object oriented but, to be honest, I can’t be bothered. It works.