Not-Device Detection javascript, perl and php code

26 01 2009

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;
}


Actions

Information

3 responses

27 01 2009
Adrian

There are some other more exact methods to detect a mobile device. My preferred one is WURFL.

27 01 2009
robmanson

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.

Mobile device recognition

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.

28 11 2009
Dwight Vietzke

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.

Leave a comment