margenn

On a recent project I needed a way to know if a user is using a mobile device to visit the site I was building and, if so, I wanted a little more info about the device, OS and browser used.

Before baking my own solution, I checked existing solutions such as the great WURFL, well known framework’s own solutions like CodeIgniter’s and other quite good scripts like php-mobile-detect, detectmobilebrowsers.mobi or mobiforge.com.

None did what I needed in a simple and lightweight way:

WURFL

  • Not straightforward to implement. 
  • Device database updates have to be done manually and periodically (at least twice a year) to stay up to date (Ughh). 
  • Heavy on the server (poor performance). 

CodeIgniter’s user agent class

Works well for mobile detection but it does not tell you either the OS or browser used.

php-mobile-detect

I like this one a lot but, unfortunately it doesn’t detect every browser/os/device I wanted, it has some bugs and I haven’t tested its regular expressions.

detectmobilebrowsers.mobi

Very good script but, unfortunately it doesn’t detect every browser/os/device I wanted. However, I used it as a reference.

mobiforge.com

This script is more suited towards detecting old mobile devices (feature phones).

So in the end I made my own script.

All I wanted was a helper function that would execute once per page load and set some global variables.

Those of you who prefer or need an OOP approach should modify the php-mobile-detect class to your needs.

Here’s my function:

<?php
/*
 * Lightweight detector of mobile devices, OSs & browsers
 * Copyright 2012  Túbal Martín  (email: tubalmartin@gmail.com)
 * License: GPL2
 */

if ( ! function_exists('mobile_detector') )
{
    // Global vars
    $is_mobile = false;
    $is_iphone = $is_ipad = $is_kindle = false;
    $is_ios = $is_android = $is_webos = $is_palmos = $is_windows = $is_symbian = $is_bbos = $is_bada = false;
    $is_opera_mobile = $is_webkit_mobile = $is_firefox_mobile = $is_ie_mobile = $is_netfront = $is_uc_browser = false;


    function mobile_detector($debug = false)
    {
        global $is_mobile;

        // Check user agent string
        $agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';

        if (empty($agent)) {
            return;
        }

        $mobile_devices = array(
            'is_iphone' => 'iphone',
            'is_ipad' => 'ipad',
            'is_kindle' => 'kindle'
        );
        
        $mobile_oss = array(
            'is_ios' => 'ip(hone|ad|od)',
            'is_android' => 'android',
            'is_webos' => '(web|hpw)os',
            'is_palmos' => 'palm(\s?os|source)',
            'is_windows' => 'windows (phone|ce)',
            'is_symbian' => 'symbian(\s?os|)|symbos',
            'is_bbos' => 'blackberry(.*?version\/\d+|\d+\/\d+)',
            'is_bada' => 'bada'
        );
        
        $mobile_browsers = array(
            'is_opera_mobile' => 'opera (mobi|mini)', // Opera Mobile or Mini
            'is_webkit_mobile' => '(android|nokia|webos|hpwos|blackberry).*?webkit|webkit.*?(mobile|kindle|bolt|skyfire|dolfin|iris)', // Webkit mobile
            'is_firefox_mobile' => 'fennec', // Firefox mobile
            'is_ie_mobile' => 'iemobile|windows ce', // IE mobile
            'is_netfront' => 'netfront|kindle|psp|blazer|jasmine', // Netfront
            'is_uc_browser' => 'ucweb' // UC browser
        );
        
        $groups = array($mobile_devices, $mobile_oss, $mobile_browsers);
        
        foreach ($groups as $group) {
            foreach ($group as $name => $regex) {
                if (preg_match('/'.$regex.'/i', $agent)) {
                    global $$name;
                    $is_mobile = $$name = true;
                    break;
                }
            }
        }
        
        // Fallbacks
        if ($is_mobile === false) {
            $regex = 'nokia|motorola|sony|ericsson|lge?(-|;|\/|\s)|htc|samsung|asus|mobile|phone|tablet|pocket|wap|wireless|up\.browser|up\.link|j2me|midp|cldc|kddi|mmp|obigo|novarra|teleca|openwave|uzardweb|pre\/|hiptop|avantgo|plucker|xiino|elaine|vodafone|sprint|o2';
            $accept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : '';

            if (false !== strpos($accept,'text/vnd.wap.wml')
                || false !== strpos($accept,'application/vnd.wap.xhtml+xml')
                || isset($_SERVER['HTTP_X_WAP_PROFILE'])
                || isset($_SERVER['HTTP_PROFILE'])
                || preg_match('/'.$regex.'/i', $agent)
            ) {
                $is_mobile = true;
            }
        }

        // DEBUGGER OUTPUT
        if ($debug === true) {
            echo '<strong>User Agent: '.$agent.'</strong><br>';
            foreach ($GLOBALS as $k => $v) {
                if (strpos($k, 'is_') !== false) {
                    echo '<span style="color:'.($v ? 'green':'red').';">$'.$k.'</span><br>';
                }
            }
        }

    }

    // execute inmmediatly
    mobile_detector();

}

I have created a Gist so you can download or fork the code.

This function should only be called once per page load and preferably as soon as possible.

This function adds the following variables to the global scope:

Is it a mobile?

  • $is_mobile

Any famous device?

  • $is_iphone (Apple iPhone)
  • $is_ipad (Apple iPad)
  • $is_kindle (Amazon Kindle)

What mobile OS?

  • $is_android (Android OS)
  • $is_bada (Bada OS)
  • $is_bbos (Blackberry OS)
  • $is_ios (Apple iOS)
  • $is_palmos (Palm OS)
  • $is_symbian (Symbian OS)
  • $is_webos (Hp WebOS)
  • $is_windows (Windows Phone OS and older)

What mobile browser?

  • $is_firefox_mobile (Mozilla Fennec)
  • $is_ie_mobile (IE)
  • $is_netfront (NetFront)
  • $is_opera_mobile (Opera Mobile or Mini)
  • $is_uc_browser (UC Browser)
  • $is_webkit_mobile (Webkit)

The initial value of these variables is false.

You can test/debug the plugin results (debug mode) here.

If you need to debug the function, call it passing true as a parameter and the function will output the results.

If you use Wordpress to build websites and you’re reading this post let me tell you I already developed a plugin for Wordpress based on this function.

Share your thoughts!!

Tags: mobile detector device php browser

Happy 2012 to everyone!!

As some of you may already know, it’s been a year now since I published my first ever plugin for Wordpress: Youtube shortcode

A year ago, version 1.0 was born and currently we’re at version 1.8.2. Much has been improved since its first release and that wouldn’t have been possible without the great community Wordpress has.

Version 1.0 was dead simple and lacked many features that today are present such as:

  • Fluid & static videos (responsive design approach)
  • Mobile & RSS readers compatibility
  • TinyMCE button
  • Support for many more custom and official parameters
  • Support for the AS2 video player

During the past year I also showed some love for good documentation and support creating a website for the plugin’s documentation. The purpose behind its creation was to give users the possibility to see the plugin in action. One month after its release Google Analytics reports it’s doing quite well with 130 unique visitors each day.

Wordpress.org gives both users and developers essential data about a plugin’s success such as the total number of downloads or the community rating and so far, people all over the world have downloaded the plugin 27.000 times and 10 people have given it a five stars rating.

All in all it’s been an exciting and very encouraging year!! A big thank you!!

What’s coming this year?

This year, I plan to release version 1.9 somewhere between january and march along with a Pro version.

Version 1.9 will give you the option to store default settings for every YouTube video on your website but will also allow you to override any default setting on a per video basis.

Pro version will offer a new and exciting performance mode that will allow your websites to load much much faster and its price will be quite affordable.

Stay tuned!!

Tags: wordpress youtube plugin shortcode