[Top]
   
Look at also other topic groups, which I have done!
You can return to this topic group by using this menu and the link Table of topic groups in the top of the page.
 
 
Search:
[Help]

Browser detections

The basic problem detecting browser with PHP is that only User Agent strings can be detected by using the predefined variables, for example $HTTP_USER_AGENT.

<?php print $HTTP_USER_AGENT; ?>

The function above prints the UA string of your browser if the settings of the server allows it. It is however to better to define a new variable for that, for example $userBrowser = $_SERVER['HTTP_USER_AGENT']; (I use variable $userBrowser in my examples).

Server-specific notes:

  1. In the settings of the PHP-parser might be register_globals=Off. In that case $HTTP_USER_AGENT doesn't work. $HTTP_USER_AGENT etc. are build-in application-level variables, which can normally be used in any situations. When the author defines variables by using the keyword global they concerns the page, where the script has been used (by using for example the include function it is possible to emulate application level variables). By using the $_SERVER variable it is possible to create new script-level global variables. For example the code

    <?php
    global $userBrowser;
    $userBrowser = $_SERVER['HTTP_USER_AGENT'];
    print $userBrowser;
    ?>
    should print the UA string of your browser, which you can see below:
    CCBot/2.0 (http://commoncrawl.org/faq/)

One of the most problematic browsers to detect are Netscape 4.x series browsers. The only string, which can be used is Mozilla and the version number of it. Below is a user agent string of a Netscape 4.x browser:

Mozilla/4.79 [en] (Win98; U)

The string Mozilla/4. use almost all browsers in the market and other browsers should be able to shut off. Below is a code, where by using the function stristr() has been detected MS IE, Opera and Mozilla Gecko browsers and the string Mozilla/4 (using this functions name are not case-sensitive).

$MSIE = (stristr($userBrowser, "MSIE") || stristr($userBrowser, "Internet Explorer"); /* The first argument of the function stristr is the string, where the sub-string should be found. The second argument is the searched sub-string. */
$Opera = stristr($userBrowser, "Opera");
$Moz4 = stristr($userBrowser, "Mozilla/4");
$Gecko = stristr($userBrowser, "Gecko");
$NN4 = ($Moz4 && !$MSIE && !$Gecko && !$Opera);

That method doesn't detect such browsers, which has the string Mozilla/4. and which are not MS IE, Opera or Netscape browsers. It is possible to detect all Mozilla between a certain range. The reasonable range could be browsers, which are newer than Mozilla/4.00 and older than Mozilla/5.0. The detection can be done by using function floatval(), which converts string into decimal values (they are called also as double):

$Moz4All = ((floatval(substr(stristr($userBrowser, "Mozilla"),8, 3)) > 4.0) && (floatval(substr(stristr($userBrowser, "Mozilla"),8, 3)) < 5.0)); /* The first value of the substr() function determines after how characters the sub-string starts and latter defines the length of the sub-string. If in the end of the searched string would be empty space or character they are not harmful because that possibility has been taken account. It is not necessary to check the value by using the ctype_digit() function. According to an e-email when using the float data type it is important to check that the data type real is float. It is also possible to split comparative floats with the explode()-function from the points, where are commas and then compare separately values before and after commas by using the intval() function. */

Server-specific notes:

  1. All servers don't support the floatval() function because it is supported starting from PHP 4.2.0 but the functionality can be get in older versions of PHP by a user-defined function.

    php.net: floatval

In some cases the needed conversion function is intval() (for example (intval(substr(stristr($userBrowser, "Gecko"),6, 8)) for Gecko/20001108). My browser detections don't take account all browsers but most however. It is also worth to note that some browsers user either the rendering engine of MS IE or Mozilla Gecko browsers. Those browsers have been taken account among MS IE and Gecko detections. On browser, which is worth to mention is Konqueror, which is available in Linux platform and Safari in the Mac platform. It it easy to take account it at the same way as other browsers. Below is a detection string of Safari:

Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/48 (like Gecko) Safari/48

By using JavaScript-detections could be asked if (document.layers), which is only supported in the Netscape 4.x series browsers. The problem is however that it not possible to make detections using variables (for example var 4NN4 = (...);) and it is necessary especially way to take account Netscape 4.x. In my mind JavaScript-based detection works in that mean worse than PHP-detections.

The another remarkable area is unknown DOM-browsers. By using JavaScript-detections it is possible to ask if (document.getElementById) and UA string are not needed at all. It is not any reason to try to know all browsers, which support DOM. If for example all DOM-capable browsers needs certain CSS I would use the following system:

  1. The author defines common CSS for all such browsers, which support DOM and the proprietary DHTML of MS IE.
  2. That CSS has been defined so that Netscape 4.x doesn't read it. In my mind the easiest way it to generate comments around such CSS-files, which are not intended for Netscape 4.x series:
    <?php
    include('...');
    /* That file defines variables. */
    if ($NN4){echo "<!--\n";}?>

    <link rel="stylesheet" ...
    ...

    <?php if ($NN4){echo "-->\n";}?>
  3. Browser-specific additional files has been get by PHP (a model[S] and related variable definitions[S]).

It is possible to combine JavaScript and PHP detections. First as far as possible with PHP and for browsers, which PHP-detections don't fit PHP will generate necessary JavaScript or a reference to a JavaScript file:

...
else {
echo "<script language=\"JavaScript\" type=\"text/javascript\" src=\"../Navigoinnit/AdviceBrowserSpecificCSS.js\"></script>"; }

In addition of ordinary (X)HTML-browsers thema are also browser of cellular phones in order to read WML-pages. WML 1.x resembles so much XHTML that with relative small modifications it is possible to create from the same material different versions for both WML 1.x and (X)HTML capable browser.

Compared WML 1.x with HTML WML has few elements. In this solution has been used elements, which WML 1.x capable browsers don't identify but they should not be harmful for them. WML has also special elements and attributes, which don't belong to XHTML. Following elements are common (I have also a table[S] of WML 1.2 elements):

If WML-browsers are intended to support at least following matters should be taken account:

Instead of ordinary browser detections WML-browsers could in principle detect by detecting which mime-types, which tells which file formats browsers directly (without plug-ins) support. Used variables are either $_SERVER['HTTP_ACCEPT'] or $HTTP_SERVER_VARS['HTTP_ACCEPT'] (the latter must be used if global variables are not allowed). Below is a test, which tells if your browser informs enough supported mime-types. It also list what mime-types yuor browser informs (below is the test code):

Your browser tells enough supported mime-types to the server!

Your browser tells following mime-types to the server:
text/html
application/xhtml+xml
application/xml;q=0.9
*/*;q=0.8
<?php
$MimeTypes = $HTTP_SERVER_VARS['HTTP_ACCEPT'];

if (stristr($MimeTypes, "application/xhtml+xml") || stristr($MimeTypes, "text/html"))
{print "...";}

else {print "...";}

print "...";

$aMimeTypes = explode(",",$_SERVER['HTTP_ACCEPT']);

for($i=0;$i<count($aMimeTypes);$i++){
echo $aMimeTypes[$i] . "<br />";
?>

The test succeeded well enough with an Opera and a Gecko browser, but not with MS IE 5.5. The system could work, if all WML-browsers inform that they support WML and in the first condition has been asked stristr($MimeTypes, "wml". If all WML-browsers don't do that, it is necessary to find some other detection method.

phpfreaks: Mime Types.

The alternative of the modularization, which I have proposed is heavy XSLT-transformation, where document have fist been created as XML-documents, which then have been transformed either WML 1.x or XHTML documents.

New cellular browsers support WML 2.0, which base on XHTML. For those browser the optimal solution could base on simplified XHTML-documents. In order to take account them it might be necessary to create different navigation and structure modules of Web-pages.

[Top]