Detecting Mobile Browsers
Oct 15th, 2007 by Greg Bulmash
UPDATE: The code has just been tested against the WURFL database of over 6,750 different mobile browser User Agent IDs, and proved 94.34% effective at catching the User Agent IDs in their database, yet providing NO false positives on the 63 most popular browser/OS combos on the desktop. And remember, that's just one of three checks this function performs.
UPDATE #2: Need help using the code in this article? I've written a second article with code to help you handle your mobile users when this piece of code detects them.
When it comes to detecting PDA and cell phone web browsers visiting your web site, you'd think there would be a standard "hi, I'm a mobile browser" handshake that a mobile browser would send to your server. And if you thought that (like I did), you'd be wrong.
Let's skip the story and get to the PHP code.
While working on a new site, I wanted to make a few pages "mobile aware" so they reformatted themselves for mobile phones. And while I could do some of that with CSS, detecting mobile browsers with PHP so I can customize the HTML that's delivered is even better.
But I found that there's no standardized way this works. A lot of sites had a piece of the puzzle, but most were only partially effective. I even ran across a British doofus who wanted $20 for a commercial license to code that couldn't catch a Treo.
So, what I did, was... hunt the triggers that identify most PDA and phone browsers without scoring false positives on major browsers. I culled through huge lists of User Agent IDs to find unique bits I could test for, plus found a couple of other tests at various sites, and pulled them all together. Oddly enough, despite all the pages I went to that discussed how to do this, none of them did all of these tests.
I've tested the following code against 63 desktop browser versions across Linux, Mac, and multiple versions of Windows, using a free trial at BrowserCam. From Konqueror to AOL to Opera to Firefox to IE, no false positives. That pretty much guarantees no false positives for 99.9% of your visitors using desktop browsers.
For catching mobile browsers, it's caught every mobile browser I've thrown at it... 3 real ones (Palm Blazer, Opera Mini, Google's web to plain old text converter) and 2 simulated ones (Sony K750, Nokia N70). It also scored 94.34% against a database of 6,788 mobile browser User Agent ID codes via the WURFL database. And since its WURFL score was only based on one of three different tests the script does, and the ones it wasn't catching were from more obscure browsers, I'd estimate this little chunk of code should be able to identify 97% of mobile visitors, if not more.
if(isset($_SERVER["HTTP_X_WAP_PROFILE"])) return true;
if(preg_match("/wap\.|\.wap/i",$_SERVER["HTTP_ACCEPT"])) return true;
if(isset($_SERVER["HTTP_USER_AGENT"])){
$uamatches = array("midp", "j2me", "avant", "docomo", "novarra", "palmos", "palmsource", "240x320", "opwv", "chtml", "pda", "windows\ ce", "mmp\/", "blackberry", "mib\/", "symbian", "wireless", "nokia", "hand", "mobi", "phone", "cdm", "up\.b", "audio", "SIE\-", "SEC\-", "samsung", "HTC", "mot\-", "mitsu", "sagem", "sony", "alcatel", "lg", "eric", "vx", "NEC", "philips", "mmm", "xx", "panasonic", "sharp", "wap", "sch", "rover", "pocket", "benq", "java", "pt", "pg", "vox", "amoi", "bird", "compal", "kg", "voda", "sany", "kdd", "dbt", "sendo", "sgh", "gradi", "jb", "\d\d\di", "moto");
foreach($uamatches as $uastring){
if(preg_match("/".$uastring."/i",$_SERVER["HTTP_USER_AGENT"])) return true;
}
}
return false;
}
It's pretty simple. Line 1 of the function checks to see if the browser is sending a WAP profile. No desktop browser would want or need to, and based on my testing, none do. OTOH, Blazer on my Treo 700p sends one, but Opera Mini doesn't, so it's far from the only test needed.
The second line looks for WAP formats in the HTTP Accept string, which tells the server the types of content the browser can accept.
The rest of the code checks the User Agent ID for bits of text that you'll find in mobile browser IDs but not in the IDs of major desktop browsers. Each of these text snippets are meaningful indicators pulled from real PDA and mobile phone User Agent IDs.
If you'd like to test this code, I've got a test page at http://www.brainhandles.com/testmobile.php. Not only will it tell you if your browser registers as mobile, but what tests out of the three (WAP profile, WAP accepted, User Agent substrings) your mobile browser scored a hit on. If the script scores a false positive (desktop browser shows up as mobile) or doesn't identify your mobile browser as mobile, instructions for reporting it are provided.
SECOND UPDATE: It's been brought to my attention that some site owners like the iPhone's method of rendering regular (i.e. not optimized for mobile) pages and want to exclude the iPhone from the list. Luckily, the Safari on the iPhone is nice enough to identify itself in its User Agent ID. To exclude the iPhone, add in the following line of code near the top as the first check the script performs.
That will create an exclusion for the iPhone and treat it as if it were a desktop browser.
Thanks, and I hope this works for you.
Will it detect Opera Mobile?
@HeavyWave,
Opera Mini (the java based version of Opera for mobile phones) is detected by the script.
You can test this by going to the Opera Mini Simulator and then browsing to my test page at http://www.brainhandles.com/testmobile.php
Didn't know there's a simulation. I just used my phone to check.
Nice script, thanks a lot.
[...] #1 Web sites can automatically detect what platform a visitor is accessing the site through. Go to facebook.com on your phone, you end up at m.facebook.com. Its hassle-free to the end user. [...]
[...] While a lot of people have written in with kudos on my PHP code for detecting mobile browsers, others have written in with questions on how to use it. [...]
DIGG: This link does not appear to be a working link. Please check the URL and try again.
Sorry, i tried to digg ya. Great job man.
Opera Mini and Opera Mobile are different...
http://www.opera.com/products/
[Editor's Note: But in his follow-up, HeavyWave said he'd checked the script/demo with his phone, so it's a bit of a moot point.]
If we're to believe http://www.mobileopera.com/reference/ua , Opera Mobile should be detected no problem, since it contains a platform and device strings at the very least in the UA string.
Anyway, thank you from me aswell for this code snippet. Works like a charm
P.S.: it was interesting to find out that preg_match is actually faster than stripos. I always assumed it'd be the opposite
Hi,
I'm just learning PHP.
Can you explain to me why you do the foreach loop -- rather than just formatting $uamatches directly in regex syntax?
Is this more efficient processing, or more organized for you, or avoids some possible error getting thrown?
Thanks!
Jane,
This is actually complex enough an answer to deserve its own post.
- Greg
Script looks great but I wish you had a ASP/vbscript version.....Like your site by the way....
Larry
Larry,
detection for browsers in ASP(VBScript):
<%
str = Request.ServerVariables("http_user_agent")
if InStr(1, str, "msie", 1) 0 then
browserIE = "true"
elseif InStr(1, str, "firefox", 1) 0 then
browserFirefox = "true"
elseif InStr(1, str, "safari", 1) 0 then
browserFirefox = "true"
elseif InStr(1, str, "iphone", 1) 0 then
browserIPhone = "true"
end if
if browserIPhone "" then response.redirect ("index_iphone.asp")
%>
pretty long winded but effective none the less, hope it helps!!
Kier
Greg's Note: This is a browser "sniffer" looking for "Msie", "Firefox", "Safari", or "iphone" in the user_agent string and then setting a string related to that browser as true. You'll need to act upon whether
browserIE,browserFirefox(which it sets to true for Firefox or Safari), orbrowserIPhoneis true, not on whether a mobile browser has been detected. And if you base your action on just that, a lot of smaller browsers that are desktop-based, but don't use one of those 4 strings in their user_agent strings, will be treated as mobile browsers.Also, unless you have a specific page for an IPhone at index_iphone.asp, you may want to take out the last line of code.
Awesome!
I just created a SQL Server function using C# and .NET to build a pre-screener before we hit WURFL and other device databases. This post directly influenced the final code. Thanks for the ideas! I can now do this right in a database query, thousands of user-agents in seconds.
Thanks!
Greg Harris
http://www.mobilytics.net
It seems that the checkmobile function creates a false positive on AOL 10. I have the function exactly as you have it here, and it is returning true on the preg_match on the 'eric' user agent string.
In looking at the Sony/Ericsson user agents, I think changing it to 'erics' should work. Please let me know what you come up with also.