While server based detection using mod_rewrite or similar will provide a much better level of performance, sometimes you just want to handle it from within a script. Below are examples in javascript, perl and php so you can choose your language/environment. I would strongly recommend using a server side script (e.g. perl or php) but I’ve included a javascript version for reference. Of course if you’re cutting edge then you could run the javascript on the server-side too.
I hope you find this code useful. If you find any bugs or logical errors please let me know.
NOTE: This code is designed to support 3 key classes of device – PC, iPhone and POM (Plain Old Mobile). See the comments by the winmo detection that shows where you may like to extend this for other high-end devices (e.g. Windows Mobile or Symbian).
Javascript Example:
/**
* Copyright © 2009
* Rob Manson, Sean McCarthy and http://MOBusiness.com.au
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Javascript Not-Device Detection Function
* Find out what type of device this is
* returns string - either pc, pom or iphone
*/
function _not_device_detection() {
var ua = navigator.userAgent;
var qs = window.location.search.substring(1);
var agent = "error";
var re = {
"pcswitch" : new RegExp("pc", "i"),
"pomswitch" : new RegExp("pom", "i"),
"iphoneswitch" : new RegExp("iphone", "i"),
"iphone" : new RegExp("iP(hone|od)(;|\s)", "i"),
"winmo" : new RegExp("Windows\s+CE", "i"),
"linux" : new RegExp("Linux", "i"),
"windows" : new RegExp("Windows", "i"),
"mac" : new RegExp("OS\s+(X|9)", "i"),
"solaris" : new RegExp("Solaris", "i"),
"bsd" : new RegExp("BSD", "i")
};
if (qs.match(re.pcswitch)) {
/* This assumes you have a single query string value of "pc" */
agent = "pc";
} else if (qs.match(re.pomswitch)) {
/* This assumes you have a single query string value of "pom" */
agent = "pom";
} else if (qs.match(re.iphoneswitch)) {
/* This assumes you have a single query string value of "iphone" */
agent = "iphone";
} else if (ua.match(re.iphone)) {
/* This user agent should be an iPhone/iPod */
agent = "iphone";
} else if (ua.match(re.winmo)) {
/* This user agent should be a Windows Mobile device - you may want a special class for this and possibly high-end Symbian too */
agent = "pom";
} else if (
(!ua.match(re.linux)) &&
(!ua.match(re.windows)) &&
(!ua.match(re.mac)) &&
(!ua.match(re.solaris)) &&
(!ua.match(re.bsd))
) {
/* This user agent is not Linux, Windows, a Mac, Solaris or BSD */
agent = "pom";
} else {
/* Otherwise assume it's a PC */
agent = "pc";
}
return agent;
}
Perl Example:
######################################################################################################
## Copyright © 2009
## Rob Manson, Sean McCarthy and http://MOBusiness.com.au
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see .
##
## Perl Not-Device Detection method
## Find out what type of device this is
## returns string - either pc, pom or iphone
######################################################################################################
sub _not_device_detection() {
# either pass in \%ENV or pack the UA and QUERY into a hashref and pass that in
my $env = shift;
my $ua = $env->{HTTP_USER_AGENT};
my $qs = $env->{QUERY_STRING};
my $agent = "error";
if ($qs =~ /^pc$/i) {
# This assumes you have a single query string value of "pc"
$agent = "pc";
} elsif ($qs =~ /^pom$/i) {
# This assumes you have a single query string value of "pom"
$agent = "pom";
} elsif ($qs =~ /^iphone$/i) {
# This assumes you have a single query string value of "iphone"
$agent = "iphone";
} elsif ($ua =~ /iP(hone|od)(;|\s)/i) {
# This user agent should be an iPhone/iPod
$agent = "iphone";
} elsif ($ua =~ /Windows\s+CE/i) {
# This user agent should be a Windows Mobile device - you may want a special class for this and possibly high-end Symbian too
$agent = "pom";
} elsif (
(!$ua =~ /Linux/i) &&
(!$ua =~ /Win/i) &&
(!$ua =~ /OS\s+(X|9)/i) &&
(!$ua =~ /Solaris/i) &&
(!$ua =~ /BSD/i)
) {
# This user agent is not Linux, Windows, a Mac, Solaris or BSD
$agent = "pom";
} else {
# Otherwise assume it's a PC
$agent = "pc";
}
return $agent;
}
PHP Example:
/**
* Copyright © 2009
* Rob Manson, Sean McCarthy and http://MOBusiness.com.au
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* PHP Not-Device Detection Function
* Find out what type of device this is
* returns string - either pc, pom or iphone
*/
function _not_device_detection() {
$ua = $_SERVER['HTTP_USER_AGENT'];
$qs = $_SERVER['QUERY_STRING'];
$agent = "error";
if (preg_match('/^pc$/i', $qs)) {
/* This assumes you have a single query string value of "pc" */
$agent = "pc";
} else if (preg_match('/^pom$/i', $qs)) {
/* This assumes you have a single query string value of "pom" */
$agent = "pom";
} else if (preg_match('/^iphone$/i', $qs)) {
/* This assumes you have a single query string value of "iphone" */
$agent = "iphone";
} else if (preg_match('/.*iP(hone|od)(;|\s).*$/i', $ua)) {
/* This user agent should be an iPhone/iPod */
$agent = "iphone";
} else if (preg_match('/Windows\s+CE/i', $ua)) {
/* This user agent should be a Windows Mobile device - you may want a special class for this and possibly high-end Symbian too */
$agent = "pom";
} else if (
(!preg_match('/Linux/i', $ua)) and
(!preg_match('/Win/i', $ua)) and
(!preg_match('/OS\s+(X|9)/i', $ua)) and
(!preg_match('/Solaris/i', $ua)) and
(!preg_match('/BSD/i', $ua))
) {
/* This user agent is not Linux, Windows, a Mac, Solaris or BSD */
$agent = "pom";
} else {
/* Otherwise assume it's a PC */
$agent = "pc";
}
return $agent;
}

There are some other more exact methods to detect a mobile device. My preferred one is WURFL.
Hi Adrian,
har…I think we established your love of WURFL during our discussion on your blog earlier 8)
I also still stand by my comments that WURFL is a great tool for general device capability research – but a terrible tool for doing live profiling if you try to use it to cater for too many different capabilities.
http://beradrian.wordpress.com/2008/10/10/mobile-device-recognition/#comment-199
Either you create a design nightmare or you use automatic size and format transcoding and lose control over image quality and design integrity. You also drive up complexity.
I have yet to see a good business case that justifies a site supporting hundreds if not thousands of different individual device profiles. I believe they should only support somewhere between 3 and 10 depending upon your business model and target audience.
Don’t get me wrong…I LOVE WURFL too…I just think we have really different views on how to use it.
I agree with both the above comments to some degree. I have been putting together some code for device detection and will probably incorporate the above code (the Perl version). I use WURFL Device Data for detection but strip out the capabilities I don’t need, which does reduce the complexity and size a bit. I also use it as the ‘fallback’ when javascript doesn’t tell the perl site script what size a user’s display is, since all I really want to know is what size device display the visitor is using. This also means I don’t do the computationally heavy WURFL stuff if it isn’t necessary.
And I agree that trying to design a site for thousands of devices is probable not efficient use of your time. But being able to define certain site parameters, when necessary, can be a very good thing.
Thanks for the code.