Reputation: 4811
This code fails to work for IE8 and other older versions of IE.
I rewrote the code, now i have 2 methods, and still failure ...
Why? What can't be found?
the way i call the function:
if (BrowserVersionChecker::is_old_browser()==1) {
//popup here
}
the class:
<?php
class BrowserVersionChecker {
/**
Figure out what browser is used, its version and the platform it is
running on.
The following code was ported in part from JQuery v1.3.1
*/
public static function is_old_browser() {
$old = 0;
$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
// Identify the browser. Check Opera and Safari first in case of spoof. Let Google Chrome be identified as Safari.
if (preg_match('/opera/', $userAgent)) {
$name = 'opera';
} elseif (preg_match('/webkit/', $userAgent)) {
$name = 'safari';
} elseif (preg_match('/msie/', $userAgent)) {
$name = 'msie';
} elseif (preg_match('/mozilla/', $userAgent) && !preg_match('/compatible/', $userAgent)) {
$name = 'mozilla';
} else {
$name = 'unrecognized';
}
// What version?
if (preg_match('/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/', $userAgent, $matches)) {
$version = $matches[1];
} else {
$version = 'unknown';
}
// Running on what platform?
if (preg_match('/linux/', $userAgent)) {
$platform = 'linux';
} elseif (preg_match('/macintosh|mac os x/', $userAgent)) {
$platform = 'mac';
} elseif (preg_match('/windows|win32/', $userAgent)) {
$platform = 'windows';
} else {
$platform = 'unrecognized';
}
$version = intval($version);
if (($name == 'opera') && ($version <= 11)) {
$old = 1;
}
if (($name == 'safari') && ($version <= 5)) {
$old = 1;
}
if (($name == 'msie') && ($version <= 8)) {
$old = 1;
}
if (($name == 'mozilla') && ($version <= 7)) {
$old = 1;
}
// $arr = array(
// 'name' => $name,
// 'version' => $version,
// 'platform' => $platform,
// 'userAgent' => $userAgent
// );
//
// echo '<pre>';
// print_r($arr);
return $old;
// return array(
// 'name' => $name,
// 'version' => $version,
// 'platform' => $platform,
// 'userAgent' => $userAgent
// );
}
//not used any more - deprecated
public static function is_old_browser2() {
$old = 0;
$browser = get_browser(null, true);
print_r($browser);
if (!empty($_SERVER['HTTP_USER_AGENT'])) {
// IE <= 7
// User Agent: Opera/9.80 (Windows NT 6.1; U; en) Presto/2.10.229 Version/11.61
if (preg_match('#msie\s+(\d+)\.(\d+)#si', $_SERVER['HTTP_USER_AGENT'], $matches)) {
if ($matches[1] <= 8) {
$old = 1;
}
}
// Firefox <= 7
// User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
elseif (preg_match('#Firefox/(\d+)\.(\d+)[\.\d]+#si', $_SERVER['HTTP_USER_AGENT'], $matches)) {
if ($matches[1] <= 7) {
$old = 1;
}
}
// Safari < 5
// User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.52.7 (KHTML, like Gecko) Version/5.1.2 Safari/534.52.7
elseif (preg_match('#Version/(\d+)[\.\d]+ Safari/[\.\d]+#si', $_SERVER['HTTP_USER_AGENT'], $matches)) {
if ($matches[1] < 5) {
$old = 1;
}
}
// opera < 11
// User Agent: Opera/9.80 (Windows NT 6.1; U; en) Presto/2.10.229 Version/11.61
elseif (preg_match('#Opera/[\.\d]+.*?Version/(\d+)[\.\d]+#si', $_SERVER['HTTP_USER_AGENT'], $matches)) {
if ($matches[1] < 11) {
$old = 1;
}
}
}
return $old;
}
}
Upvotes: 0
Views: 496
Reputation: 168843
I strongly recommend not using PHP to do browser checking, especially if the purpose is to provide different output for different browsers.
In fact, browser checking in general is considered bad practice these days. Your code says it was cribbed from jQuery; it’s worth knowing that this feature in jQuery has been deprecated for some time, and removed entirely from recent versions.
So your PHP code is based on code that has been removed from jQuery because they considered it bad practice. That doesn't sound good.
So why it is considered bad practice?
Firstly, the User Agent string should not be considered reliable – not only can it very easily be spoofed (most browsers have an option to change it), but also some proxies, firewalls and anonymiser tools may alter it or strip it out completely. You cannot rely on it being correct or present.
Secondly, it may not always be useful anyway. For example, your code checks for Opera. Opera currently use their own rendering engine, but are soon going to switch to Webkit. This will completely change their browser, but your test will give the same result either way. Not really very useful. Your code also assumes that all Webkit browsers are Safari, which is clearly wrong.
Your code doesn’t have any ability to adapt to new browsers, future versions of existing browsers, or new rendering engines. The browser world is changing rapidly; your code is going to struggle to keep up with it.
And finally, your code describes various browser versions as “old”, but without any differentiation between them. The capabilities of Opera 10, IE7 and Firefox 2 are wildly different from each other. You haven’t told us what you intend to do if you get an “old” browser, but it's likely to be inappropriate for at least some of the browsers you do it to.
So if that’s not recommended, what is the alternative?
The alternative is feature testing. This is typically done in the browser itself using Javascript. The best example of this is a tool called Modernizr. This is a Javascript library that you plug into your page. It analyses what the user’s browser is capable of, and sets a bunch of flags on the site that you can then use in your CSS or Javascript. This makes it easy to spot when a browser lacks a specific feature, and easy to deal with it. The Modernizr site has excellent documentation, so I won’t go too far explaining here; just to recommend you take a look.
There are also a large number of javascript tools called ‘Polyfills’, which are designed to make older browsers work with some of the newer features you may want to use. There are polyfills for pretty much every feature you could need, so if your issue is with browsers not supporting a particular feature, there’s a good chance you can deal with it.
And finally, some browser features are just eye candy anyway. If the issue is with features like rounded corners or gradients, etc, where the page will still be useable if they aren’t there, consider simply letting the old browsers render the page without them.
A combination of the above techniques can make some very advanced sites work on very old browsers.
But I must use server-side browser detection, it’s the only way!
If you’ve rejected my arguments, and you still want to do browser testing in PHP, I would still recommend throwing away your code, because PHP does provide the functionality you need, built-in. Look up the get_browser()
function.
This function uses a browser info file called browsecap.ini (which you’ll need to download separately) to help it determine which browser is being used and what it’s capable of. These browsecap.ini files can be downloaded easily enough, and more importantly, it’s easy to keep them up-to-date as new browser versions are released. (well, easier than rewriting your code every few months).
You can download an up-to-date browsecap.ini file from here: http://tempdownloads.browserscap.com/
(note: this is a temporary URL and may change in the future; if it doesn’t work, a quick visit to your favourite search engine will give you other sources for browsecap.ini files)
If you go down this route, please bear in mind what I said at the beginning of this answer – you cannot rely on the contents of the User Agent string. Be aware of that, and be prepared to handle cases where the UA string is invalid, incorrect or just plain blank.
Finally, on a different note, if you are planning to serve different output according to the user agent string, you should also be aware that it may affect your search engine rankings. Google in particular watches for sites that give a different output for its crawler compared to normal browsers. It sees this as "masking", and actively penalises sites that do it. This isn't what you're intending (you're just trying to deal with different browser capabilities), but if you need to be careful how you do it, and how the output differs, because Google might mis-interpret it.
I hope that helps.
Upvotes: 1
Reputation: 20913
Instead of tearing your hair out dealing with individual regex cases, why not use something like UA-Parser-js - a JavaScript-based User-Agent String Parser (available as a jQuery plugin too), which attempts to provide:
It works (with a few flaws), but covers many of the browser versions commonly in use.
Upvotes: 0