UPDATE 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.

function checkmobile(){

if(isset($_SERVER["HTTP_X_WAP_PROFILE"])) return true;

if(preg_match("/wap\.|\.wap/i",$_SERVER["HTTP_ACCEPT"])) return true;


// 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.

if(preg_match("/iphone/i",$_SERVER["HTTP_USER_AGENT"])) return false;

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.

54 Responses to “Detecting Mobile Browsers”
  1. HeavyWave says:

    Will it detect Opera Mobile?

  2. Greg Bulmash says:


    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

  3. HeavyWave says:

    Didn't know there's a simulation. I just used my phone to check. :)

    Nice script, thanks a lot.

  4. [...] #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. [...]

  5. [...] 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. [...]

  6. Alex Grim says:

    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.

  7. john says:

    Opera Mini and Opera Mobile are different...


    [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.]

  8. whoever says:

    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 :P

  9. jane says:


    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?


  10. Greg Bulmash says:


    This is actually complex enough an answer to deserve its own post.

    - Greg

  11. Larry says:

    Script looks great but I wish you had a ASP/vbscript version.....Like your site by the way....


  12. kier says:


    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!!


    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), or browserIPhone is 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.

  13. Greg Harris says:


    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.


    Greg Harris

  14. Brandon Eley says:

    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.

  15. [...] 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 [...]

  16. James Duvall says:

    Thanks Greg! It works great.

  17. sd says:

    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.

  18. ansgar says:

    Hi, thanks for your snippet!

    There's a false positive wir following user agent:

    Microsoft Internet Explorer 4.0 (compatible; MSIE 7.0; Windows NT 6.0; FunWebProducts; SIMBAR={EE6D7371-250B-4A40-9B2F-C9311D99A0D6}; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; Swapper 1.0.6)
    Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; FunWebProducts; SIMBAR={EE6D7371-250B-4A40-9B2F-C9311D99A0D6}; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; Swapper 1.0.6)

    I assume "Swapper" triggers this.

  19. Greg Bulmash says:

    Yup, Swapper does. It triggers the WAP substring identifier. Which phone/browser is this from?

  20. ansgar says:

    I'm not quite sure, I guess it's a IE 7 with some weird extension. On a desktop, no phone.

  21. Oliver says:

    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?

  22. Kenny says:

    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 ????


  23. Laurent says:

    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.


  24. Ben says:

    Very nice! Works well. You saved me the trouble of looking up all HTTP_USER_AGENT possibilities.

    Thanks a lot!


  25. Synapticfury says:

    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.

  26. himenez says:

    I want to suggest a good solution, it's call "Apache Mobile FIlter".
    The URL of the project is: https://sourceforge.net/projects/mobilefilter/

  27. vinod says:

    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..

  28. Keith says:

    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;

  29. Keith says:

    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 line if(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.


  30. Toby says:

    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.

  31. Idel says:

    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

  32. Luke Dearnley says:

    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

  33. Luke Dearnley says:

    oh just noticed SynapticFury already mentioned OfficeLiveConnector.... oops!

  34. Rich G says:

    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,


  35. Jon Wallace says:

    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??


  36. [...] translated the PHP function from brainhandles.com to detect mobile devices to [...]
    [Editor's note - he translated it into Perl]

  37. Dan T. Man says:

    Nice script. Add WebOS to uamatches to catch the Palm Pre

  38. s says:

    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!

  39. [...] 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 [...]

  40. Idel says:

    Now the "Apache Mobile Filter" is one of the modules of "Apache Module Registry" portal (http://modules.apache.org/search.php?id=1787)

  41. tiong says:

    Nice piece of code and thanks for the tutorial.

  42. jodamn says:

    Thanks a lot - this is very useful!

  43. Gayle says:

    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?

  44. Roo says:

    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.

    • Greg Bulmash says:

      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.

      • Roo says:

        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?

      • Greg Bulmash says:

        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.

  45. David says:

    Hi, Greg,

    I test your code and detectmobilebrowser.com, your code is much better than detectmobilebrowser.com. Thanks for you great work

  46. [...] To achieve our goals, we will implement a small plugin. Before implementing this plugin we need a function that checks whether or not the current user is using a mobile device. You could use a smart solution like WURFL to do this. However, for our example, we will use a simple function that returs true if the user is using a mobile device and false otherwise. You’ll find dozens of functions that will do the job if you google for it. I’ll use a function that I found at Brain Handles. [...]

  47. Mike says:

    Here's an article I wrote which includes examples in PHP and Perl specifically designed to detect mobile browsers and redirect to different pages on your site. The article includes downloadable examples and a fully functional testing implementation.

    Perl: http://www.mlynn.org/2010/07/mobile-device-detection-and-redirection-with-perl-and-cgi/
    PHP: http://www.mlynn.org/2010/06/mobile-device-detection-and-redirection-with-php/

    Example and Test: http://www.mlynn.org/uatest

    Hope this helps!


Get an angel for your site An Angel Watches Over This Site