dotMobimobiThinkingmobiForgemobiReadyDeviceAtlasfind.mobiInstant Mobilizer

Lightweight Device-Detection in PHP

Section Feature image
Posted by ronan 2 years 36 weeks ago
Bookmark and Share

One problem that keeps cropping up when developing mobile content is how to differentiate between mobile devices and desktop browsers. We need to be able to do this before we can think about content adaptation. The "proper" way to do this is to use a full device database such as DeviceAtlas (see our tutorial here) or WURFL, but this approach has its problems. One potential problem is that you may not be in a position to get WURFL installed at your hosting location. Secondly, full device detection imposes a load on your server that may be problematic.

Luckily, there are solutions to this problem that, while not as reliable as full detection, may suffice for many cases. The following PHP code implements a mobile device detection algorithm that works for a large percentage of mobile browsers out there. This code is the work of Andy Moore (mobiForge profile) and you can find the original here. The algorithm used is fairly lightweight -- the code is mostly based on a list of about 90 well-known mobile browser UA string snippets, with a couple of special cases for Opera Mini, the W3C default delivery context and some other Windows browsers. The code also looks to see if the browser advertises WAP capabilities as a hint.

In our experience, this code does a fairly good job. It could probably be improved but it's certainly not a bad start, and is lightweight enough not to cause major problems.

<?php
 
$mobile_browser = '0';
 
if(preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone)/i', strtolower($_SERVER['HTTP_USER_AGENT']))) {
    $mobile_browser++;
}
 
if((strpos(strtolower($_SERVER['HTTP_ACCEPT']),'application/vnd.wap.xhtml+xml')>0) or ((isset($_SERVER['HTTP_X_WAP_PROFILE']) or isset($_SERVER['HTTP_PROFILE'])))) {
    $mobile_browser++;
}    
 
$mobile_ua = strtolower(substr($_SERVER['HTTP_USER_AGENT'],0,4));
$mobile_agents = array(
    'w3c ','acs-','alav','alca','amoi','audi','avan','benq','bird','blac',
    'blaz','brew','cell','cldc','cmd-','dang','doco','eric','hipt','inno',
    'ipaq','java','jigs','kddi','keji','leno','lg-c','lg-d','lg-g','lge-',
    'maui','maxo','midp','mits','mmef','mobi','mot-','moto','mwbp','nec-',
    'newt','noki','oper','palm','pana','pant','phil','play','port','prox',
    'qwap','sage','sams','sany','sch-','sec-','send','seri','sgh-','shar',
    'sie-','siem','smal','smar','sony','sph-','symb','t-mo','teli','tim-',
    'tosh','tsm-','upg1','upsi','vk-v','voda','wap-','wapa','wapi','wapp',
    'wapr','webc','winw','winw','xda','xda-');
 
if(in_array($mobile_ua,$mobile_agents)) {
    $mobile_browser++;
}
 
if (strpos(strtolower($_SERVER['ALL_HTTP']),'OperaMini')>0) {
    $mobile_browser++;
}
 
if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'windows')>0) {
    $mobile_browser=0;
}
 
if($mobile_browser>0) {
   // do something
}
else {
   // do something else
}   
 
?>

The changes changes made from Andy's original version are:

  • Adding the W3C UA string (Default Delivery Context)
  • Specal case detection for Opera Mini
  • Catch-all exception for devices with Windows in the UA string (Opera 9 for Windows was being recognised as a mobile device)

If anyone has any improvements on this code, or implementations for other languages, please let us know!

See also an ASP version.

 


Posted by ronan 2 years 36 weeks ago

ronan's picture

Mobile nerd.

Posted by pbateman 2 years ago

Would this not be better placed in a function returning true as soon as it has detected it's a mobile device to prevent it continuing its way through the rest of the code

Posted by eduardoraad 2 years ago

I ported the code to Java and added some simple stuff. I will be adding more features later. You can download it from Google Code:

http://code.google.com/p/mobiledevicedetector/

Posted by fritzbrause 2 years ago

Hi there!

thanks for the nice little code. I tried WURFL, to be sure, that it is a mobile device, which visits my page, but WURFL fails on Windows Mobile Smartphones. So i try this piece of code, but it also dont recognize my Windows Mobile Testphone ;-)
The Problem lies in the last check, which overides all others:
if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'windows')>0) { $mobile_browser=0; }

Windows Mobile (and older Versions of the Windows CE platform for PocketPC and Smartphones), use a small Internet Explorer for browsing. Which send an agent like this:

HTC_P3300 Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 7.6)

This example shows the default Agent of a HTC P3300 Smartphone with Windows Mobile 6.
As there is a "Windows" in the text, the code above detects a desktop-system.

To make it easy (this time) i just added a new line (just below the one above), which fixes this problem (hopefully nobody uses an opera mini on a Windows smartpohne :):

if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'iemobile')>0) {
$mobile_browser++;
}

Regards!
Markus

Posted by spellboy 2 years ago

To detect the opera mobile browser (and many other) you have to add the following code:

	if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),' ppc;')>0) {
		$mobile_browser++;
	}

Kind regards,
Christopher

http://m.spellboy.com - your mobile spell checker

Posted by hidayath 2 years ago

any one have ASP version of this code

hidayath
www.MobiBlaze.com

hidayath www.MobiBlaze.com

Posted by ruadhan 1 year ago

We've recently added an asp version here.

Ruadhan O'Donoghue
mobiForge

Posted by promorock 1 year ago

What is the best way to implement this?

Jonathan Morgan PromoRock www.promorock.com

Posted by ruadhan 1 year ago

You just need to include this code at the top of your PHP page. Then at the end of the script you will see we have to options: mobile or not-mobile. In the branch for mobile you can put your PHP code for your mobile page, and in the not-mobile branch you put in your non-mobile content.

Does this help?

Ruadhan O'Donoghue
mobiForge

Posted by kimurray 1 year ago

Greetings: Can I include that php code on the html index page of my website? You have already guessed I am a code dummy and dont savvy php at all!
If I can where should it go and what code do I use to redirect to my .mobi site please.

Posted by ruadhan 1 year ago

Yes, probably the most simple way would be to include at the top of your index page, and then send the user to the appropriate content.

Another approach would be to have the code at the top of every page, so whatever the entry point, the user would get the right page

Ruadhan O'Donoghue
mobiForge

Posted by Roberto Trama (not verified) 1 year ago

There is also another problem in the code, which I tested on my website and hidden by the overriding check fo the string containing "windows": the array to recognize mobile user agents includes the string "oper" that will cause to consider as mobile device some Opera browsers. The check for Windows browsers will exclude Opera for Windows, but not Opera for Linux. The HTTP_USER_AGENT: Opera/9.50 (X11; Linux i686; U; en), as example, will redirect to the mobile version of the website. I have excluded the string "oper" from the array and now redirection does not occurr for all Opera browsers on desktops. Which other mobile browsers (exluding Opera) begin with "oper"?

Posted by geigers 1 year ago

Thanks for this little piece of code, it's just what I needed. Still working on testing it out. I needed to re-write it in PL/SQL (Oracle Stored Procedure Language) for an application I am working on. I did find a problem with this section of the code:

if (strpos(strtolower($_SERVER['ALL_HTTP']),'OperaMini')>0) {

It will never evaluate as true. An "strtolower" is done on $_SERVER['ALL_HTTP'] and then an "strpos" is run to compare against "OperaMini" <--- notice there are CAPS in the compare value (O and M). Should be:

if (strpos(strtolower($_SERVER['ALL_HTTP']),'operamini')>0) {

Scott Geiger

Posted by surin 1 year ago

Its very useful program, i really appreciate the devi.mobi for describe it and provide it for me. i again thanks for this, please keep it updating according to new changes in mobile environments.. thanks

Posted by majorsoft 1 year ago

Thx - good knowledge.

Is there anyone out there that can help me setup a small site - with mobile access to detect device and provide a specific version of a jar file for download?

Looking for a mobile turnkey solution that does not require week to install and configure.

Any ideas?

Thx again

Major

Posted by mkmajeed 1 year ago

thanks for such a nice script, i have been looking for such script in past. thanks again

Muhammad Kashif Majeed

My Blog

Posted by anthonyhand 1 year ago

Hi!

I just published a PHP script for detecting mobile devices on my web site:

www.hand-interactive.com/resources/detect-mobile-php.htm

The code is very flexible with a fairly rich API, can detect specific platforms (e.g., iPhone vs. Symbian S60), or classes of devices (e.g., smartphones vs. generic mobile device), and more. The code is downloadable and freely shared under a Creative Commons license. (Though a donation is gratefully accepted!)

I've also published some JavaScript code which closely mirrors the PHP one, except that the JavaScript library is of limited utility (due to limited JavaScript support in browsers on mobile devices.)

Please take a look at it. Extensions and fixes greatly appreciated, as well!

Cheers,
Anthony

*************************************************************

Anthony Hand,
Freelance Mobile User Interface Designer

w: www.hand-interactive.com

*************************************************************

Posted by cwbash 1 year ago

I've got this code running and find everything fine down to the line which says
if($mobile_browser>0)
do something

What I'd like to do at that point is redirect this link to another page. I'm told from other articles that the solution is to use "header (Location:", but when I do so, I'm told "Cannot modify header information - headers already sent".

There's nothing in my php script except the php code (line 1 is the "<?php" so the classic example of inserting HTML at the beginning hasn't been done. Any thoughts about why headers have already been sent? I would like suggestions about how to "do something" that can stay on the server. If I can't, can you supply code that would set an HTML or Javascript variable so just a few lines on the client would do the redirect?

You can see my full code at http://www.lighthousesrus.org/mobile/test.php

Posted by robman 1 year ago

Hi Ronan,

I'd be interested in what you (and the people that are using your script) think of the discussion I've started with James (see my post here).

I think there's some real benefits in turning your approach around the other way - we call this the "Not-Device" Detection Strategy.

From our experience over the last 2 years this provides better coverage and better performance, without the maintenance issues as new devices are released.

roBman

Posted by pascalv 1 year ago

I used the original code, and changed the comments given above.

Also I changed the detection for "windows". If there is a "Windows CE", then it doesn't have to look further.

My new changed code:

$mobile_browser = '0';
 
if(preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone)/i', strtolower($_SERVER['HTTP_USER_AGENT']))) {
    $mobile_browser++;
}
 
if((strpos(strtolower($_SERVER['HTTP_ACCEPT']),'application/vnd.wap.xhtml+xml')>0) or ((isset($_SERVER['HTTP_X_WAP_PROFILE']) or isset($_SERVER['HTTP_PROFILE'])))) {
    $mobile_browser++;
}    
 
$mobile_ua = strtolower(substr($_SERVER['HTTP_USER_AGENT'],0,4));
$mobile_agents = array(
    'w3c ','acs-','alav','alca','amoi','audi','avan','benq','bird','blac',
    'blaz','brew','cell','cldc','cmd-','dang','doco','eric','hipt','inno',
    'ipaq','java','jigs','kddi','keji','leno','lg-c','lg-d','lg-g','lge-',
    'maui','maxo','midp','mits','mmef','mobi','mot-','moto','mwbp','nec-',
    'newt','noki','oper','palm','pana','pant','phil','play','port','prox',
    'qwap','sage','sams','sany','sch-','sec-','send','seri','sgh-','shar',
    'sie-','siem','smal','smar','sony','sph-','symb','t-mo','teli','tim-',
    'tosh','tsm-','upg1','upsi','vk-v','voda','wap-','wapa','wapi','wapp',
    'wapr','webc','winw','winw','xda','xda-');
 
if(in_array($mobile_ua,$mobile_agents)) {
    $mobile_browser++;
}
 
if (strpos(strtolower($_SERVER['ALL_HTTP']),'operamini')>0) {
    $mobile_browser++;
}
 
if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),' ppc;')>0) {
	$mobile_browser++;
}
 
if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'windows ce')>0) {
	$mobile_browser++;
}
else if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'windows')>0) {
    $mobile_browser=0;
}
 
if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'iemobile')>0) {
	$mobile_browser++;
}
 
if($mobile_browser>0) {
   // do something
   // YES MOBILE
}
else {
   // do something else
   // NOT MOBILE
}

Posted by torweb 1 year ago

I have a version of this working but the above looks better. My question is how do I complete the code...the part:

if($mobile_browser>0) {
// do something
// YES MOBILE
}
else {
// do something else
// NOT MOBILE
}

I'm new at this....

Thanks

Posted by onesearch 1 year ago

Hi, Dont want to sound stupid, but, New to PHP and was wondering the same as the last message, What do i replace/add to complete the code.

Thanks in Advance

Posted by magicman2000 1 year ago

has anyone tried a web service like handsetdetection.com? I think that it is PHP friendly

Posted by JMANJ 49 weeks ago

Thanks for this code ! After some tests we identified a problem with Macintosh browsers such like Opera.
For example, the UserAgent of a typical Opera installation on Mac OS is : "Opera/9.63 (Macintosh : PPC Mac OS X : U : fr) Presto / 2.1.1"

In this case, the code identifies the browser like a mobile_browser which is not the case. It comes from the $mobile_agents array which contains the string "oper". So each Opera browser on Macintosh is seen like a mobile browser (not the on Windows because of the 'windows' test).

Any idea on a patch to avoid that (deleting "oper" string doesn't look like the best solution) ?
Thanks in advance,
Jmanj

Posted by EseMismo 46 weeks ago

Hi,

I've been reading recently some posts, and maybe a little explanation 'bout basic app architecture could bring some light - where to go, and how to take advantage of the "location" function.
This post has a twofold goal:
* Show an explicit URL to go (wether mobile or not)
* Overcome the infamous "Cannot modify header information - headers already sent" error message ;-)

What you need is a page that looks something like this:

<? PHP
 
/*
Put here any PHP code - i.e. the detection script
AND/OR any functions, includes, etc.
       ...
       ...
*/
 
/*
Now, it's **VERY IMPORTANT**
This holds the entire page's output buffer, until it's time to SEND HEADERS
*/
ob_start();
?>
 
        <HTML>
        <!-- Your HTML code here, if any - i.e. your CSS, JS and title
               ...
               ...
        -->
        </HTML>
 
<? PHP
if($mobile_browser>0) {
   // YES MOBILE - do something
   header("Location: mobile.php"); // go to mobile URL
}
else {
   // NOT MOBILE - do something else
   header("Location: desktop.php"); // go to desktop URL
}
 
/*
Now, it's **VERY IMPORTANT AGAIN**
This allows headers & content to be sent to the browser
*/
ob_end_flush();
?>

Really, this example could grow a bit more, to become something called "page controller" (look in Google or Wikipedia for more on programming patterns): you have an almost blank "index" page, and depending on some conditions, you execute or call (include or require) one or another "code chunk".
Of course, this is just a skeleton - you should taylor it to your specific needs - but while being basic, it works.
Hope you find it useful.

EseMismo

Posted by john.boxall 45 weeks ago

Be careful with this kind of thing - you're playing with fire.

This script will always redirect mobile devices to the mobile page - depending on how well you've designed your mobile site and whether you've hidden functionality or not - this may not always be what the user wants.

Play it safe and allow the user a way to force either the full or mobile versions of the site - you can do this easily with an extra GET parameter on requests:

In your HTML always include likes to both versions of the site w/ the special force mode parameters:

<a href="http://www.example.org/?mobile">View Mobile Site</a>
<a href="http://www.example.org/?full">View Full Site</a>

In your PHP always check for the parameters before you do the User-Agent happy dance:

<?php
 
if ($_GET['mobile']) {
 $is_mobile = true;
}
 
if ($_GET['full']) {
 $is_mobile = false;
}

Cheers,

John

P.S

Dotmobi dudes, this input box is super small - we're not typing a tweet here - this is for a post!

Update in my habit of reading the oldest posts first I missed James' post on doing what I described above:
http://www.mobiforge.com/designing/story/a-very-modern-mobile-switching-algorithm-part-ii

Posted by microgers206 40 weeks ago

hey guys, i am currently building a buddy of mine a web site for his business, and I am trying to create a mobile site (as his index is a flash intro, and cannot be seen by most mobile devices.) I am extremely new to the mobile device web design, and am not too experienced with php or asp. Can you give me a step by step to introducing this redirect on my site? thank you very much and greatly appreciated.

Posted by ifuschini 38 weeks ago

Hi,
you can use Apache Mobile Filter and the keep the information of capability as environment variable, I think it's a good solution for work with any language supported with Apache Web Server (Ruby, PHP, JSP, perl).

See the info here: http://www.idelfuschini.it/it/apache-mobile-filter-v2x.html

Mobile & Web 2.0 Consultant

Posted by Teli 35 weeks ago

pascalv wrote:
I used the original code, and changed the comments given above.

Also I changed the detection for "windows". If there is a "Windows CE", then it doesn't have to look further.

My new changed code:

$mobile_browser = '0';
 
if(preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone)/i', strtolower($_SERVER['HTTP_USER_AGENT']))) {
    $mobile_browser++;
}
 
if((strpos(strtolower($_SERVER['HTTP_ACCEPT']),'application/vnd.wap.xhtml+xml')>0) or ((isset($_SERVER['HTTP_X_WAP_PROFILE']) or isset($_SERVER['HTTP_PROFILE'])))) {
    $mobile_browser++;
}    
 
$mobile_ua = strtolower(substr($_SERVER['HTTP_USER_AGENT'],0,4));
$mobile_agents = array(
    'w3c ','acs-','alav','alca','amoi','audi','avan','benq','bird','blac',
    'blaz','brew','cell','cldc','cmd-','dang','doco','eric','hipt','inno',
    'ipaq','java','jigs','kddi','keji','leno','lg-c','lg-d','lg-g','lge-',
    'maui','maxo','midp','mits','mmef','mobi','mot-','moto','mwbp','nec-',
    'newt','noki','oper','palm','pana','pant','phil','play','port','prox',
    'qwap','sage','sams','sany','sch-','sec-','send','seri','sgh-','shar',
    'sie-','siem','smal','smar','sony','sph-','symb','t-mo','teli','tim-',
    'tosh','tsm-','upg1','upsi','vk-v','voda','wap-','wapa','wapi','wapp',
    'wapr','webc','winw','winw','xda','xda-');
 
if(in_array($mobile_ua,$mobile_agents)) {
    $mobile_browser++;
}
 
if (strpos(strtolower($_SERVER['ALL_HTTP']),'operamini')>0) {
    $mobile_browser++;
}
 
if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),' ppc;')>0) {
	$mobile_browser++;
}
 
if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'windows ce')>0) {
	$mobile_browser++;
}
else if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'windows')>0) {
    $mobile_browser=0;
}
 
if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'iemobile')>0) {
	$mobile_browser++;
}
 
if($mobile_browser>0) {
   // do something
   // YES MOBILE
}
else {
   // do something else
   // NOT MOBILE
}

------------------------

Hello -

The above code does not work and the original code does not work either. Ofcourse, I justed copied and pasted the code but have had no luck and ideas would be appricated.

Thanks for your time,
Teli

Posted by David123 31 weeks ago

My php script except the php code (line 1 is the "<?php" so the classic example of inserting HTML at the beginning hasn't been done. Any thoughts about why headers have already been sent? I would like suggestions about how to "do something" that can stay on the server

Posted by David123 31 weeks ago

Thank you for your expression of picture I'll just try my iphone device...

Posted by turbowebguy 30 weeks ago

Why not just make a landing page with an option: Click here for mobile site
I'm kidding. Great page, cool site, lots of info.

Posted by econn_designer 17 weeks ago

Hello Everyone

I am new in making mobile based website. My question is :
[i]My website is fully static and made in simple html pages. I have made the mobile version and make its subdomain "www.m.abc.com"
Now is there any script which can redirect the user when he/she open my website on mobile and redirect he/she when seeing my website on desktop

Will wait for your help
Regards

Posted by whoisstan 13 weeks ago

made a very compact php mobile detection method if you need one:

function is_mobile(){
	$regex_match="/(nokia|iphone|android|motorola|^mot\-|softbank|foma|docomo|kddi|up\.browser|up\.link|";
	$regex_match.="htc|dopod|blazer|netfront|helio|hosin|huawei|novarra|CoolPad|webos|techfaith|palmsource|";
	$regex_match.="blackberry|alcatel|amoi|ktouch|nexian|samsung|^sam\-|s[cg]h|^lge|ericsson|philips|sagem|wellcom|bunjalloo|maui|";	
	$regex_match.="symbian|smartphone|midp|wap|phone|windows ce|iemobile|^spice|^bird|^zte\-|longcos|pantech|gionee|^sie\-|portalmmm|";
	$regex_match.="jig\s browser|hiptop|^ucweb|^benq|haier|^lct|opera\s*mobi|opera\*mini|320x320|240x320|176x220";
	$regex_match.=")/i";		
	return isset($_SERVER['HTTP_X_WAP_PROFILE']) or isset($_SERVER['HTTP_PROFILE']) or preg_match($regex_match, strtolower($_SERVER['HTTP_USER_AGENT']));
}