Detecting Mobile Browsers
Posted by Greg Bulmash in Techno Thoughts, Web Programming, tags: PHPUPDATE 11/30/09: After two years, I have decided to stop maintaining and updating this code. I'm not currently using it and it was getting to be in need of an overhaul with all the devices that keep changing the landscape. I'd suggest the open source DetectMobileBrowser.com.
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.
UPDATE December 2008: Looks like IE8 has a trick of adding all sorts of software to the user agent string. Someone sent me one that listed the version of Zune software they were using and "Creative AutoUpdate" which was triggering the substring search for "pda", meaning a whole bunch of people were getting false positives on IE8. I've added an exception to catch the "Creative AutoUpdate" string.
UPDATE June 2009: As reported in the comments and occasionally by e-mail, the Office Live Connector in IE 8 was causing false positives with the check to see if you're running an NEC phone. People were adding their own lines to the code to check for this, but I figured I'd group the checks for known false positives the same way the grouping for known positives is done. That way you can just add an item to the array and not keep adding lines and lines of code.
UPDATE July 2009: Small code clean-up and addition of another false positive exclusion to the "badmatches" array. Please keep those notes and comments coming.
UPDATE August 2009: WebOS added to the uamatches array to catch Palm Pre. Please keep those notes and comments coming.
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"])){
// Quick Array to kill out matches in the user agent
// that might cause false positives
$badmatches = array("OfficeLiveConnector","MSIE\ 8\.0","OptimizedIE8","MSN\ Optimized","Creative\ AutoUpdate","Swapper");
foreach($badmatches as $badstring){
if(preg_match("/".$badstring."/i",$_SERVER["HTTP_USER_AGENT"])) return false;
}
// Now we'll go for positive matches
$uamatches = array("midp", "j2me", "avantg", "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", "erics", "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","webos");
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.
You can now add "iphone" to the badmatches array and have it treated as a false positive if you want to exclude iPhone.
Thanks, and I hope this works for you.


Entries (RSS)
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.
[...] found this script at http://www.brainhandles.com/2007/10/15/detecting-mobile-browsers/Â that detects mobile phones. It’s very simple to implement. I call this script and use it to [...]
[...] a good starting point, but consider also using WURFL http://www.brainhandles.com/2007/10/15/detecting-mobile-browsers/ [...]
Thanks Greg! It works great.
I wondered why my Firefox (on a regular Windows PC) was detected as "mobile" by a lot of sites, that wanted then to display me their "mobile" version.
Turns out that I had once an extension to enable it to wiew WAP, so the option (in "about:config") "network.http.accept.default" was set to "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5,text/vnd.wap.wml;q=0.6".
I reseted it to default value and all works well since then.
So it could be a hint for people that would like to test their mobile site on a regular Firefox; just change "network.http.accept.default" accordingly.
Hi, thanks for your snippet!
There's a false positive wir following user agent:
I assume "Swapper" triggers this.
Yup, Swapper does. It triggers the WAP substring identifier. Which phone/browser is this from?
I'm not quite sure, I guess it's a IE 7 with some weird extension. On a desktop, no phone.
Hi there
I'm up against a strange one.
I've built a "project room" feature that dynamically generates an RSS feeds using mod_rewrite to parse the URL - e.g. http://www.spyfilms.com/projects/feed/ben_steiger_levine/showreel - and the Zend Framework to generate the feed based on the resulting variables.
I want iPhone users directed to the feed to be served scaled-down m4v files as the feed enclosures and everyone else - browsers, feed readers, iTunes, etc - QuickTime files of much higher resolution.
The problem is that the user agent string when viewing a feed is not the standard iPhone / iPod ua, but Apple-PubSub/65.1.1, regardless of whether the browser is desktop or mobile: i.e. *any* version of Safari has the same user agent string when viewing a feed.
Any suggestions on how t differentiate them?
Hi Everyone-
Sorry, I don't have a solution for you Oliver but I really need to ask a question to all developers of this PHP redirect script..... I actually use the script and it works flawlessly! but my host just informed me that they do not support PHP on their server. Can someone help me convert the above redirect script to ASP VB script ????
Thanks!
have you ever considered using uaprof instead of user-agent for mobile detection? There are many different user agent versions for the same phone (same specifications) while there are only a few uaprofs for every handset models. My detection mechanism is based on uaprof and uses user agent as a back up, it's working quite well.
You can try it out here: http://www.mobilemultimedia.be/en/
Check out for MobileDetect, it's a free API to insert mobile detection in your pages.
Tell me what you think.
Thanks
Laurent
Very nice! Works well. You saved me the trouble of looking up all HTTP_USER_AGENT possibilities.
Thanks a lot!
Ben
Thanks for this script. I thought I should update everyone on a problem I'm having. A lot of user agents have "OfficeLiveConnector" in them which triggers the substring search for "NEC" causing a lot of false positives. A few other false positives include user agents with "MSN Optimized" which triggers the substring search for "pt" and "SeekmoToolbar" (spyware) which triggers the substring search for "moto". I have corrected them in a manner similar to the "Creative AutoUpdate" fix. These three cases account for 99% of my false positives so far, so hopefully we'll have clear sailing from here on out.
Hi,
I want to suggest a good solution, it's call "Apache Mobile FIlter".
The URL of the project is: https://sourceforge.net/projects/mobilefilter/
my company have 2 versions one mobile and regular website,
my problem is when i accessing the website in opera 9.60 it takeing me to mobile version is there any solution or setting to take to regular website in asp mobile detection code..
thanks in advance..
I use IE8 and was getting the false positive, so I researched a bit and found out that Microsoft is sending a Trident user agent. I modified the code as appears below and it now works perfect. Thanks for the script. Its great.
if(preg_match("/Trident/i",$_SERVER["HTTP_USER_AGENT"])) return false;Checked my site with my wife's laptop which has not gone to IE8 and found that it was routing to the WAP site. So, I replaced the
if(preg_match("/Creative\ AutoUpdate/i",$_SERVER["HTTP_USER_AGENT"])) return false;which didn't seem to have any effect. So, I added the following lineif(preg_match("/MSIE/i",$_SERVER["HTTP_USER_AGENT"])) return false;. Now it seems to work just fine. I can't test with other versions of IE or Mozilla, so if anyone else notices a problem please tell me.Thanks.
Thanks. The algorithm works very well, though I did have to make a few tweaks.
First, I removed "pt" from the list of strings to search through, because that is the language code for Portuguese and I had a user agent string with that code. What type of mobile device was this supposed to detect, and is there another string that can be used instead?
Second, I added "archos" to the list. When I saw this user agent string, "Opera/9.02 (Linux armv5tejl; U; ARCHOS; GOGI; a605; en),Opera 9.02", I did a Google search, and it does represent a mobile device.
I have published the new version of Apache Mobile Filter, now the filter is give to you the information of capabilities as apache environment.
Now you can develope in any language (php,jsp, ruby etc.) and have the information of mobile capability.
Read more info here: http://www.idelfuschini.it/it/apache-mobile-filter-v2x.html
Hi Greg,
thank you for an excellent script. I have used it on some sites.
Recently however I had a few people using IE7 (on a desktop machine) who were complaining they got redirected to the mobile version of our site.
After a bit of frigging round I discovered they had the string OfficeLiveConnector in their User Agent which was triggering the script to think they were browsing from an NEC phone (since it contains the letters NEC)
To fix this I added a line into your script after this one:
if(preg_match("/Creative\ AutoUpdate/i",$_SERVER["HTTP_USER_AGENT"])) return false;and that line is:
if(preg_match("/OfficeLiveConnector/i",$_SERVER["HTTP_USER_AGENT"])) return false;maybe you would consider adding this to your script above. Or if not hopefully people using this great script and having the same problem will read this comment and have their problem solved.
thanks again
:L
oh just noticed SynapticFury already mentioned OfficeLiveConnector.... oops!
Greg -
This is great code - thanks.
We recently found a problem - in IE8 the string 'msn OptimizedIE8' may appear in the agent string, which matches on 'pt' -
I recommend adding 'OptimizedIE8' to the $badmatches array.
Thanks again,
Rich
Thanks. Added.
This looks like a fab script... i have tried to implement it but it seems not to work? Could someone advise what is the best way to use this code? I get parse errors when i try and use it??
Thanks
Seems I accidentally added an extra comma when making a quick edit a couple of days ago. Fixed that. Should be fine now.
[...] translated the PHP function from brainhandles.com to detect mobile devices to [...]
[Editor's note - he translated it into Perl]
Nice script. Add WebOS to uamatches to catch the Palm Pre
You aren't detecting skyfire browser with this. I am using your newest version of the script, which has been a HUGE help to me.
Add this line to check for skyfire:
if(isset($_SERVER["HTTP_X_SKYFIRE_PHONE"])) return true;
Keep up the good work!
[...] WuLongTi on Oct.01, 2009, under Hints and Tips, Web Work Greg Bulmash over at brainhandles.com came up with this awesome little php function. This simple snippet will detect whether your website [...]
Now the "Apache Mobile Filter" is one of the modules of "Apache Module Registry" portal (http://modules.apache.org/search.php?id=1787)
Nice piece of code and thanks for the tutorial.
Thanks a lot - this is very useful!
The android phone by motorola won't declare false. Something in $uamatches overides
$badmatches = array("OfficeLiveConnector","MSIE\ 8\.0","OptimizedIE8","MSN\ Optimized","Creative\ AutoUpdate","Swapper","andriod","iphone");
or if(preg_match("/Android/i",$_SERVER["HTTP_ACCEPT"])) return false;
Also the lg voyager for verizon doesn't declare true. Go straight for my flash enabled site. Any Ideas?
Looks a nice script and could be exactually what I'm looking for.
I am far from the best web master in the world when it comes to writting scripts etc and hoped you could help.
With it being the holiday season I'm currently running a snow script on my website and forum.
Most mobile browsers including the iphone seem to have problems running the snow script.
Would there be a way I could implement your script so that mobile browsers would be able to ignore the snow script?
It may seem a trivial question to those in the know but it would really help my site users out and I just don't know how to do it.
Well, you can either use it to redirect them to a version of your site that doesn't have the snow script, or you could make adding the snow script to your pages conditional on them being on a desktop browser when the page is generated.
I'm hoping to make adding the snow script conditional as I think this would be easier than designing a whole new site just for mobiles at christmas.
The snow script has a function to hide snow and I have tried to edit the snow script so that if a mobile browser is detected it would not show snow, but as I don't really know what I'm doing I couldn't get it to work.
The snow script I tried to edit is here if you wanted to see it
Is there a direction/website you could point me towards that may help me learn what is needed to add your script?
Roo, for the past week or so I've been suggesting detectmobilebrowser.com instead of my code.
As for making the script conditional, your snow script is JavaScript and this script is PHP. JavaScript is client side and PHP is server side. So you'd need to write some PHP code that literally changes the JavaScript. For example, you wrap the entire snow script up in a PHP conditional statement so it only gets included in the page if the mobile condition is not met.
Or you can write a bit of PHP code to insert a "mobilebrowser" variable into your javascript, and then have your javascript react to whether it's set to true or false. Of course, many mobile browsers don't process JavaScript, so in their cases the point would be moot.
[...] http://www.brainhandles.com/2007/10/15/detecting-mobile-browsers/ [...]