PHP: Browser version number user-agent with Version/x.x.x (Safari & Opera)
Given your handful of results, this works. It may not in all cases, but it's going to reduce your processing time drastically.
I'd use a single regular expression to extract the version:
(?:version\/|(?:msie|chrome|safari|firefox|opera) )([\d.]+)
And then, since you're only searching for a handful of exact strings, you can use php's stripos()
to check for the browser string.
<?php
$useragent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1";
$browsers = Array('msie','chrome','safari','firefox','opera');
preg_match("/(?:version\/|(?:msie|chrome|safari|firefox|opera) )([\d.]+)/i", $useragent, $matches);
$version = $matches[1];
$browser = "";
foreach($browsers as $b)
{
if (stripos($useragent, $b) !== false)
{
$browser = ucfirst($b);
break;
}
}
echo "$browser: $version";
?>
The benefits of doing it this way are immediate:
- You don't need to test the useragent multiple times with the regular expression.
stripos()
is significantly faster at processing than regular expressions.
You can also play around with the regex here: http://regex101.com/r/lE6lI2
Ended up doing it a little differently since I had some trouble with some browsers with Remus' answer.
<?php
function get_useragent_info($ua)
{
$ua = is_null($ua) ? $_SERVER['HTTP_USER_AGENT'] : $ua;
// Enumerate all common platforms, this is usually placed in braces (order is important! First come first serve..)
$platforms = "Windows|iPad|iPhone|Macintosh|Android|BlackBerry";
// All browsers except MSIE/Trident and..
// NOT for browsers that use this syntax: Version/0.xx Browsername
$browsers = "Firefox|Chrome";
// Specifically for browsers that use this syntax: Version/0.xx Browername
$browsers_v = "Safari|Mobile"; // Mobile is mentioned in Android and BlackBerry UA's
// Fill in your most common engines..
$engines = "Gecko|Trident|Webkit|Presto";
// Regex the crap out of the user agent, making multiple selections and..
$regex_pat = "/((Mozilla)\/[\d\.]+|(Opera)\/[\d\.]+)\s\(.*?((MSIE)\s([\d\.]+).*?(Windows)|({$platforms})).*?\s.*?({$engines})[\/\s]+[\d\.]+(\;\srv\:([\d\.]+)|.*?).*?(Version[\/\s]([\d\.]+)(.*?({$browsers_v})|$)|(({$browsers})[\/\s]+([\d\.]+))|$).*/i";
// .. placing them in this order, delimited by |
$replace_pat = '$7$8|$2$3|$9|${17}${15}$5$3|${18}${13}$6${11}';
// Run the preg_replace .. and explode on |
$ua_array = explode("|",preg_replace($regex_pat, $replace_pat, $ua, PREG_PATTERN_ORDER));
if (count($ua_array)>1)
{
$return['platform'] = $ua_array[0]; // Windows / iPad / MacOS / BlackBerry
$return['type'] = $ua_array[1]; // Mozilla / Opera etc.
$return['renderer'] = $ua_array[2]; // WebKit / Presto / Trident / Gecko etc.
$return['browser'] = $ua_array[3]; // Chrome / Safari / MSIE / Firefox
/*
Not necessary but this will filter out Chromes ridiculously long version
numbers 31.0.1234.122 becomes 31.0, while a "normal" 3 digit version number
like 10.2.1 would stay 10.2.1, 11.0 stays 11.0. Non-match stays what it is.
*/
if (preg_match("/^[\d]+\.[\d]+(?:\.[\d]{0,2}$)?/",$ua_array[4],$matches))
{
$return['version'] = $matches[0];
}
else
{
$return['version'] = $ua_array[4];
}
}
else
{
/*
Unknown browser..
This could be a deal breaker for you but I use this to actually keep old
browsers out of my application, users are told to download a compatible
browser (99% of modern browsers are compatible. You can also ignore my error
but then there is no guarantee that the application will work and thus
no need to report debugging data.
*/
return false;
}
// Replace some browsernames e.g. MSIE -> Internet Explorer
switch(strtolower($return['browser']))
{
case "msie":
case "trident":
$return['browser'] = "Internet Explorer";
break;
case "": // IE 11 is a steamy turd (thanks Microsoft...)
if (strtolower($return['renderer']) == "trident")
{
$return['browser'] = "Internet Explorer";
}
break;
}
switch(strtolower($return['platform']))
{
case "android": // These browsers claim to be Safari but are BB Mobile
case "blackberry": // and Android Mobile
if ($return['browser'] =="Safari" || $return['browser'] == "Mobile" || $return['browser'] == "")
{
$return['browser'] = "{$return['platform']} mobile";
}
break;
}
return $return;
} // End of Function
?>
Have you heard of browscap and get_browser()
? On my install:
$info = get_browser();
echo $info->browser; // Chrome
echo $info->version; // 29.0
To use it, grab yourself a copy of a PHP version of browscap.ini from here (e.g. php_browscap.ini
), reference it in php.ini
under the browscap
directive, and you're good to go.