Page: 1, 2, 3  Next

Browser detection. HTML5 CSS3
timgolding
Status: Interested
Joined: 30 Nov 2011
Posts: 26
Reply Quote
I want to use the browser detection script to do privide different content for different user agents. Following these rules

- Does the browser support HTML5 / CSS3
- Is it an older browser
- Is it a mobile device.

For each of these rules serve up different content.

here's the code i came up with.

:: Code ::

<?php
// include script from http://techpatterns.com/downloads/php_browser_detection.php
include("includes/browser.php");

// get browser agent info
$browser_num = browser_detection( 'browser_number' );
$browser = browser_detection( 'browser_working' );
$os = browser_detection( 'os' );
$os_num = browser_detection( 'os_number' );
$mobile = browser_detection( 'mobile_test' );

/*
// echo output
echo ( $browser_num.'<br>'.
$browser .'<br>'.
$os .'<br>'.
$os_num .'<br>'.
var_export(browser_detection( 'mobile_test' ), true)
);

Chrome
535.2
webkit
mac
10.6.8

Safari
534.51.22
webkit
mac
10.6.8
''

Opera
11.52
op
mac
10.6.8
*/

// array holding start of browser support.
$html5_compat = array("moz" => 3.6, "webkit" => 400, "ie" => 9, "op" => 10);

// test for mobile then test for html5.
if($mobile!="")
{
    $use = "mobile";
}
elseif($html5_compat[$browser] < $browser_num)
{
    $use = "html5";
}
else
{
    $use = "html";
}

echo $use;

?>


Can anyone advise if this is the right way to detect the user agent is HTML5 /CSS3 compliant. Is there a better way. are the numbers of the browser version correct? Any other browsers i need to consider? Any help would be greatly appreciated.
Back to top
techAdmin
Status: Site Admin
Joined: 26 Sep 2003
Posts: 4128
Location: East Coast, West Coast? I know it's one of them.
Reply Quote
if you're doing math comparisons, you have to make sure to strip out all the non math numbers in the version numbers, ideally use something like intval($browser_nu) to pull out only the starting integer.

I'd just make the firefox test for >= 4 and not worry about 3.6, easier math, or do: engine = gecko && (browser >= 4 or strstr($browser_nu,'3.6.') )

note the last dot in the 3.6. that helps avoid fake detections of say, 2.3.6

that's pseudo code.

browser numbers can be: 2 dot, not a decimal, like 3.6.4, they can have b+23 type syntax for testing, or alpha, or other non numeric strings, so the best thing is to just test the primary integer value.

but the overall idea is good, in fact, it might be time to add in a primary data return type of html5, which now appears to really be for real and here to stay.

However, keep in mind, you want to know both if it's mobile AND if it supports html5 for general use, although your specific case will of course vary depending on the site needs.
Back to top
timgolding
Status: Interested
Joined: 30 Nov 2011
Posts: 26
Reply Quote
Thanks for the advice. I did wonder about the double dots but did a test and noticed

:: Code ::

 echo (float)"543.43.36";

// outputs 543.43

the float comparison was truncating the second dot and the numbers after. Isn't it everything before the last set of dots what i need? then i could continue to do float comparisons? Maybe a regex would be easier say

:: Code ::

preg_replace("/[^0-9\.]+/", "", $browser_num);

then do a float comparison of this. Im not sure though because i don't know exaclty what the browser_num can be? You probably know far more about user agents than me. Maybe its better to just get the first number before any dots
:: Code ::

$broswer_int = (int)$browser_num;


or

:: Code ::

preg_match("/^[0-9]+/", $browser_num, $matches);


And do a integer comparisons?

I will change firefox to 4.

Glad you think it is a good idea and would love to see the script include an html5 test of some sort. I will continue with what i am doing using your excellent script though. It's a good learning process for me.
Back to top
timgolding
Status: Interested
Joined: 30 Nov 2011
Posts: 26
Reply Quote
following your advice here's what i came up with.

:: Code ::

<?php
// include script from http://techpatterns.com/downloads/php_browser_detection.php
include("includes/browser.php");

// get browser agent info
$browser_num = browser_detection( 'browser_number' );
$browser = browser_detection( 'browser_working' );
$os = browser_detection( 'os' );
$os_num = browser_detection( 'os_number' );
$mobile = browser_detection( 'mobile_test' );

/*
// echo output
echo ( $browser_num.'<br>'.
$browser .'<br>'.
$os .'<br>'.
$os_num .'<br>'.
var_export(browser_detection( 'mobile_test' ), true)
);

Chrome
535.2
webkit
mac
10.6.8

Safari
534.51.22
webkit
mac
10.6.8
''

Opera
11.52
op
mac
10.6.8
*/

// array holding start of browser support.
$html5_compat = array("moz" => 4, "webkit" => 400, "ie" => 9, "op" => 10);

// get integer value of browser_num stripping out unwanted chars etc
preg_match("/^[0-9]+/", $browser_num, $matches);
$browser_int = (int)$matches[0];

// test for mobile then test for html5.
if($mobile!="")
{
    $use = "mobile";
}
elseif($html5_compat[$browser] < $browser_int)
{
    $use = "html5";
}
else
{
    $use = "html";
}

echo $use;

?>

Back to top
techAdmin
Status: Site Admin
Joined: 26 Sep 2003
Posts: 4128
Location: East Coast, West Coast? I know it's one of them.
Reply Quote
}
elseif($html5_compat[$browser] < $browser_int)

should be:

}
elseif($html5_compat[$browser] <= $browser_int)

I believe to avoid 4 < 4, or 10 < 10.

preg_match is less efficient than plain intval, php recommends avoiding regex unless you have to use it, the builtins like strstr or intval are more efficient.

Keep in mind that you need the true msie and the true opera numbers.

intval is also useful because it returns 0 if it's false, not null, so the following math will not kick out an error if the browser number is not numeric.
Back to top
timgolding
Status: Interested
Joined: 30 Nov 2011
Posts: 26
Reply Quote
Ah ok i didn't know that

So if i want to get the true Ie version i would use

:: Code ::

if($browser == "ie") $browser_num = browser_detection('true_ie_number');


I couldnt see how to get the true opera version though? Is my browser detection script out of date it's version 5.3.18

I didn't realise that regex was less efficient. I don't see how i can use strstr without testing every possible value individually like

:: Code ::

 strstr($browser_num,'3.');
 strstr($browser_num,'4.');
 strstr($browser_num,'5.');
 strstr($browser_num,'6.');
 strstr($browser_num,'7.');


Maybe it's enough to just use the intval function (which is new to me thanks)

:: Code ::

$browser_int = intval($browser_num);


Are you saying use one or the other? Thanks for spotting the <= bug.
This is my code

:: Code ::

<?php
// include script from http://techpatterns.com/downloads/php_browser_detection.php
include("includes/browser.php");

// get browser agent info
$browser_num = browser_detection( 'browser_number' );
$browser = browser_detection( 'browser_working' );
$os = browser_detection( 'os' );
$os_num = browser_detection( 'os_number' );
$mobile = browser_detection( 'mobile_test' );

// array holding start of browser support.
$html5_compat = array("moz" => 4, "webkit" => 400, "ie" => 9, "op" => 10);

// get true ie number
if($browser == "ie") $browser_num = browser_detection('true_ie_number');

// get integer value of browser stripping out unwanted chars etc

$browser_int = intval($browser_num);

// test for mobile then test for html5.
if($mobile!="")
{
    $use = "mobile";
}
elseif($html5_compat[$browser] <= $browser_int)
{
    $use = "html5";
}
else
{
    $use = "html";
}

echo $use;

?>


Is that an better?
Back to top
techAdmin
Status: Site Admin
Joined: 26 Sep 2003
Posts: 4128
Location: East Coast, West Coast? I know it's one of them.
Reply Quote
I wasn't suggesting using strstr, just noting that php recommends using builtin functions like strstr or intval over using regex if you can. Since intval will or should be error free, that's what I'd use in your case. Sorry if that wasn't clear. You definitely do NOT want to use strstr in this case since t will not return a number on error, nor is it fitting to the task.

the browser detection script has always returned the true opera number, which wasn't disguised like the msie true numbers in the useragent string, just noting that to make sure, that might change depending on what opera does with their useragents in the future.

For testing purposes you can also feed the browser detection script alternate UA strings for debugging / dev tasks, that was a feature added a while ago by user request.

Also of course use firefox useragent switcher list for dev and testing purposes, which I make in conjunction with the php browser detection script, for testing new features or more complex detections, like the msie true/claimed numbers for example, or the opera 9.8 vs 10 or 11 numbers. That useragent list is fairly complete and has reasonable utility, though I am not trying to keep up with the somewhat absurd version number inflation that chrome and sadly, now firefox, are engaging in. In other words, I update the list a few times a year at most.
Back to top
timgolding
Status: Interested
Joined: 30 Nov 2011
Posts: 26
Reply Quote
Well thanks kindly for all the work you are doing with the browser detection script. I think it will work great for what i intend to do for the time being. Thanks for all the help in this forum thread also. I will test it as i use it and if i find any new bugs or problems detecting new UA strings i will be sure to let you know. I guess i might have to make some tweaks myself if i find something that's not working. I can only test on new versions of chrome, firefox, opera, safari, ie, and andriod browsers and older versions of ie from ie6 upwards.
Back to top
timgolding
Status: Interested
Joined: 30 Nov 2011
Posts: 26
Reply Quote
Been looking at the user agent switcher list that should be useful for testing. Is there anyway i can feed these UA strings in to the script to test those strings. How can I feed the browser detection script alternate UA strings? I'm guessing feed it in as the third parameter

:: Code ::

 $broser_num = browser_detection( 'browser_number', '', 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.0 Safari/532.5' ) ;

Back to top
techAdmin
Status: Site Admin
Joined: 26 Sep 2003
Posts: 4128
Location: East Coast, West Coast? I know it's one of them.
Reply Quote
that's correct, 3rd parameter feeds it the ua string. I've never used that feature, as noted, it was added as a user request with a crude patch, not unlike what you're doing here in fact. Putting up code, testing, revising, etc, as you're doing here, is probably one of the best ways to get a patch in quickly, it motivates me much more than just asking for x or y, since it shows clear and real interest on someone's part for the feature in question.

You could loop that third arg with an array of ua strings, for example, which you can grab from the ua switcher list, or you can write php to read the ua list xml file directly, a lot of work though, usually all you need is a handful of tests to cover most all cases.

I think there's enough in there though to let you test what you need to test in terms of mobiles, non mobiles, false positives and so on.

Everything is documented in the script head section, failure to be clear, or if something is ambiguous in that top head doc secction, is a bug, and will be corrected if it's pointed out, especially if it's explained why it was unclear and how to make it more clear.

:: Code ::
elseif($html5_compat[$browser] <= $browser_int)


be careful with that one by the way, you have to make sure it's one of those browsers before doing a numeric math comparison >=

do:

:: Code ::
 elseif ( array_key_exists ($browser,$html5_compat) && ($html5_compat[$browser] <= $browser_int ) ) {


always make sure the tests are protected from bad data or unexpected circumstances with any web scripting.
Back to top
Display posts from previous:   
Page: 1, 2, 3  Next
All times are GMT - 8 Hours