Build device-aware mobile sites using PHP, JavaScript, and WURFL

Get started using the WURFL PHP API

With a rapidly growing mobile Web, if you haven't already started working on a PHP-driven mobile site or application, you soon will be. Detecting the capability of one mobile device among the thousands of offerings is nearly impossible with PHP alone. But with the Wireless Universal Resource FiLe (WURFL), this once daunting task becomes as simple as a few API calls to retrieve the device data you need and can use with your PHP site or application.

Share:

Chad Russell, Software Engineer and Consultant, Freelance

Chad Russell has been a software engineer and consultant for more than 13 years, working in every capacity from developer to software architect roles, specializing in open source technologies and web-based applications. With a major focus on PHP, MySQL, and JavaScript, his experience spans a broad range of industries, from small businesses to Fortune 500 companies. In addition to development, he is the co-author of two books on MySQL.



07 February 2012

Also available in Chinese Russian Portuguese Spanish

As mobile computing continues to grow, in number of devices and in number of users of those devices, more and more mobile-only or mobile-specific websites and web applications are being developed. Keeping track of all these devices, their operating system versions, the capabilities each device has, and so on can be a daunting task. Modern mobile browsers coupled with emerging standards and technologies such as HTML5 and CSS3 are helping to make device specifics less of a worry. However, many idiosyncrasies still do and most likely always will exist among devices, and it's invaluable to have that information at your disposal.

Although some rudimentary tasks, such as browser detection, are fairly easy done with PHP or JavaScript, you're still left with a lot of unknowns about the possible mobile devices accessing your site or application. Being able to detect whether a device supports Adobe® Flash®, which Ajax capabilities it can use, or whether it supports CSS spriting isn't necessarily something you can quickly determine using PHP or JavaScript alone.

Jammed-up back-end backlog?

Sign up for a free Bluemix cloud trial and fork this sample code to quickly add authentication, push notifications, and persistent mobile data to your app.

Now you can focus on the part of the app your parents actually understand. Learn more.

By using the Wireless Universal Resource File (WURFL—pronounced "were-full"), however, you can fine-tune your mobile sites and applications easily, because you know exactly what the device can and cannot do. Without WURFL, this task would be challenging if not impossible.

What is the WURFL?

From WAP to WURFL

Around 2001, a few years after the initial Wireless Access Protocol (WAP) phone launch, it became clear that there were many differences in how WAP-enabled devices handled WAP content. So, two enterprising developers—Luca Passani and Andrea Trasatti—came together to build an open source community around a shared device repository they called the WURFL. Now, 10 years later, the WURFL has continued to grow in both the number of devices in the repository and in the many programming language APIs that are available.

The WURFL is an open source Device Description Repository (DDR) project run by ScientiaMobile that aims to be an independent central repository of mobile device information. It is used by Facebook and Google as well as many other organizations both large and small. Valuable device information such as the make and version of the mobile browser being used, whether the device is a tablet, whether it can support Flash, and much more can all be found within the WURFL.

In its simplest form, the WURFL is a repository of thousands of mobile devices and their respective capabilities. The DDR consists of an XML configuration file matched with a set of APIs that allow you to retrieve a vast amount of information about a given mobile device with little effort. Using the WURFL PHP API, you can easily start using the WURFL in your mobile PHP development right away.


Exploring the WURFL

Enough talking about why to use the WURFL and what it can do: Let's explore what the data inside the WURFL looks like and what kind of information you can gather about a given device by using it.

You should familiarize yourself with the types of data found in the WURFL before you start using the DDR with the WURFL PHP API. Remember that in its simplest form the WURFL is an XML file: When you open the WURFL file, you will see all the data composed within a set of XML nodes. There are several nodes inside the WURFL file, but there are only three nodes where you will find data about a given mobile device. Table 1 shows these device nodes.

Table 1. The main WURFL device nodes
NodeDescriptionExample data
<device>The main node that holds information for the given device<device id="htc_incredible_adr6300_ver1" user_agent="Mozilla/5.0 (Linux; U; Android 2.1-update1; en-us; ADR6300 Build/ERE27) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2" fall_back="generic_android_ver2_1" actual_device_root="true">
<group>Child of the device node; contains information about a defined feature<group id="display">
<capability>Child of a group node; lists the individual capabilities of a given device, specified within a given group <capability name="physical_screen_height" value="80"/>
<capability name="physical_screen_width" value="48"/>

From Table 1, you can determine the basic XML structure for each device:

<device>
  <group>
    <capability />
    <capability />
    <capability />
  </group>
  <group>
    <capability />
    <capability />
    <capability />
  </group>
</device>

For example, if you look inside the WURFL, you will find the device entry shown in Listing 1 for the Apple iPhone 4.

Listing 1. iPhone 4 WURFL entry
  <device id="apple_iphone_ver4" user_agent="Mozilla/5.0 (iPhone; U; 
 CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, 
 like Gecko) Mobile/7D11" fall_back="apple_iphone_ver3_1_3" 
 actual_device_root="true"> 
 <group id="product_info"> 
   <capability name="model_name" value="iPhone"/> 
   <capability name="device_os_version" value="4.0"/> 
   <capability name="model_extra_info" value="4.0"/> 
   <capability name="release_date" value="2010_april"/> 
 </group> 
 <group id="playback"> 
  <capability name="playback_acodec_aac" value="lc"/> 
  <capability name="playback_mp4" value="true"/> 
  <capability name="playback_3gpp" value="true"/> 
  <capability name="playback_acodec_amr" value="nb"/> 
  <capability name="playback_acodec_qcelp" value="false"/> 
  <capability name="playback_vcodec_mpeg4_sp" value="3"/> 
  <capability name="playback_vcodec_h263_0" value="30"/> 
  <capability name="playback_3g2" value="true"/> 
  <capability name="playback_vcodec_h264_bp" value="3.0"/> 
 </group> 
 <group id="streaming"> 
  <capability name="streaming_vcodec_h263_0" value="30"/> 
  <capability name="streaming_acodec_aac" value="lc"/> 
  <capability name="streaming_3gpp" value="true"/> 
  <capability name="streaming_vcodec_h264_bp" value="3.0"/> 
  <capability name="streaming_acodec_amr" value="nb"/> 
  <capability name="streaming_preferred_protocol" value="http"/> 
  <capability name="streaming_vcodec_mpeg4_sp" value="3"/> 
  <capability name="streaming_mp4" value="true"/> 
 </group> 
</device>

From this example, you can see that there are two child group nodes inside the main device node for the iPhone 4 entry. These two nodes provide detailed information about the audio and video codecs supported on this device. But wait: Shouldn't there be more information here, such as whether the device supports Flash or PDF or if it's a tablet? Yes! You can indeed find this information in the WURFL, but because of the nature of the WURFL and how it builds on existing device information already in the repository, it's clearly not in this entry.

Because the WURFL contains thousands of device specifications multiplied by their respective capabilities, it can quickly become an increasingly complex data matrix to continue to build on and maintain. However, one of the smart things about the WURFL is how it manages this complexity.

The creators of the WURFL took the following facts about mobile devices into consideration:

  • Although browsers are different, they have many features in common.
  • Browsers and devices coming from the same manufacturer invariably evolve from the same hardware and software. Consider the Research in Motion BlackBerry Curve 9350, 9360, and 9370: The commonalities among them are many, and the differences are minimal.
  • Devices from various manufacturers may run the same software. For example, HTC, Motorola, and Samsung all have devices that run the Google Android operating system and have a browser based on the open source WebKit and Google Chrome's V8 JavaScript engine. So, most likely, each device will be similar in terms of what the browser supports.

Taking all of that into consideration allows the WURFL to be less complex and easier for the maintainers to update. In essence, the WURFL is based on a concept of a family of devices. If you look at the first device listed in the WURFL file, you will see a device with the ID generic. Everything in the WURFL file builds off of this generic device. As a new device is added that falls within a pre-existing device family, it inherits all of the capabilities of that family unless there is something specifically different for that device, at which point, the information will be added to that given device.

For example, if you look at the fall_back attribute of the <device> node in the iPhone 4 example in Listing 1, you will see that it references apple_iphone_ver3_1_3—the device ID attribute of a previous iPhone device entry in the WURFL. If you continue to follow that ID back, you end up with a device node with the attribute ID apple_iphone_ver1. Along the way, you will find additional device information, such as its preferred geolocation API, whether it supports Adobe Flash Light, and the display resolution. Some of the groups you will find are provided in Listing 2.

Listing 2. Device groups found in WURFL
<group id="ajax"> 
   <capability name="ajax_preferred_geoloc_api" value="w3c_api"/> 
</group>
<group id="display"> 
   <capability name="resolution_height" value="480"/> 
   <capability name="resolution_width" value="320"/> 
</group>
<group id="flash_lite"> 
   <capability name="flash_lite_version" value=""/> 
   <capability name="fl_wallpaper" value="false"/> 
   <capability name="fl_browser" value="false"/> 
   <capability name="fl_screensaver" value="false"/> 
   <capability name="fl_standalone" value="false"/> 
   <capability name="fl_sub_lcd" value="false"/> 
</group>

Devices

As you can see from the iPhone4 WURFL entry, every specification for a given device starts with the main <device> node. These nodes always contain the user-agent string attribute, a fall_back device attribute, and a unique ID attribute.

Groups

The WURFL contains a number of data groups. These groups are child nodes of the device node, and each defines a capability that a device may or may not support as well as more granular details about the capability found within the group node. The groups you will find today in the WURFL are product_info, wml_ui, chtml_ui>, xhtml_ui, html_ui, css, ajax, markup, cache, display, image_format, bugs, wta, security, bearer, storage, object_download, playback, wap_push, drm, streaming, mms, j2me, sms, sound_format, flash_lite, transcoding, rss, pdf, chips, smarttv, and deprecated.

An up-to-date list of groups as well as a full description of each that includes a tabular breakdown of the capabilities defined within the given group (such as the capability name, type, and description) can be found in the WURFL help document (see Resources for a link).

Capabilities

Capabilities are defined within their parent groups. All capability name attributes are unique, even between groups, so no capability name will appear more than once within a device specification. In addition, capabilities always have a value; the value of a capability is a Boolean, a string (even an empty string), or a number.

Listing 3 provides examples of actual groups—with their defined capabilities—that you can find within the WURFL.

Listing 3. The WURFL product_info group and its capabilities
<group id="product_info"> 
  <capability name="pointing_method" value="touchscreen"/> 
  <capability name="uaprof" value="http://www.blackberry.net/go/mobile/
        profiles/uaprof/9500_edge/4.7.0.rdf"/> 
  <capability name="model_name" value="BlackBerry 9500"/> 
  <capability name="brand_name" value="RIM"/> 
  <capability name="model_extra_info" value="Thunder"/> 
  <capability name="marketing_name" value="Storm"/> 
</group>

Here, you have the most commonly found group, product_info. As you can see, you can find basic information about the device, such as the model and brand name, as well as whether the device has a touchscreen and the user-agent profile.

Another commonly found group is display, shown in Listing 4, which provides details about the device's screen dimensions and resolution. This information is particularly helpful when you're trying to display a mobile site or web application correctly on a given device rather than leaving it all to guesswork.

Listing 4. Finding device screen information in the WURFL
<group id="display"> 
   <capability name="physical_screen_height" value="66"/> 
   <capability name="columns" value="36"/> 
   <capability name="dual_orientation" value="true"/> 
   <capability name="physical_screen_width" value="50"/> 
   <capability name="max_image_width" value="340"/> 
   <capability name="rows" value="32"/> 
   <capability name="resolution_width" value="360"/> 
   <capability name="resolution_height" value="480"/> 
   <capability name="max_image_height" value="440"/> 
</group>

With these two groups, you can see that the device supports PDF documents (see Listing 5) as well as the Java™ 2 Platform, Mobile Edition (J2ME). Again, you can see how useful it is to have this information about the connecting device at your disposal without having to guess or spend additional time writing code to check for these features.

Listing 5. Checking PDF support for a given device
<group id="pdf"> 
   <capability name="pdf_support" value="true"/> 
</group> 
<group id="j2me"> 
   <capability name="j2me_midp_2_0" value="true"/> 
   <capability name="j2me_cldc_1_0" value="true"/> 
   <capability name="j2me_cldc_1_1" value="true"/> 
   <capability name="j2me_midp_1_0" value="true"/> 
</group>

Working with the PHP API

The PHP API that the WURFL project provides makes it easy to start using the WURFL in your PHP development. (See Resources for a link to download the latest WURFL PHP API.) The following simple example shows how quickly and easily you can retrieve a capability for a given mobile device.

For this example, you use the getCapability method to pass in a few different capability names found within the WURFL. You retrieve the brand and model name, the device's resolution width and height, and whether the device can support PDFs and Flash. This example assumes that you have downloaded and extracted the WURFL PHP API to the web server root; you can find the code in Listing 6 within the demo directory inside the top-level WURFL PHP API directory.

Listing 6. Demo code for the PHP API example
<?php

define("WURFL_DIR", dirname(__FILE__) . '/../../WURFL/'); 
define("RESOURCES_DIR", dirname(__FILE__) . "/../resources/"); 

require_once WURFL_DIR . 'Application.php'; 

$wurflConfigFile = RESOURCES_DIR . 'wurfl-config.xml'; 

// Create WURFL Configuration from an XML config file 
$wurflConfig = new WURFL_Configuration_XmlConfig($wurflConfigFile); 

// Create a WURFL Manager Factory from the WURFL Configuration 
$wurflManagerFactory = new WURFL_WURFLManagerFactory($wurflConfig); 

// Create a WURFL Manager ($wurflManager is a WURFL_WURFLManager object) 
$wurflManager = $wurflManagerFactory->create();

Getting the latest WURFL repository

You can find the latest version of the WURFL on the project's SourceForge page (see Resources for a link). Once you start using the DDR in your PHP application, always make sure you're using the most up-to-date version. Updating the WURFL is easy: Simply download the latest version and replace your existing wurfl.xml file. Although a patch file is available, replacing your existing wurfl.xml file is the recommended approach.

First, set up the appropriate path to the application.php file (provided with the WURFL PHP API) as well as the WURFL XML file. Then, create the WURFL Manager object. The calls to retrieve specific device information are retrieved from that object.

With the WURFL Manager object created, query the WURFL for a few pieces of data, as shown in Listing 7.

Listing 7. Querying the WURFL for data
// This line detects the visiting device by looking at its HTTP Request ($_SERVER) 
$requestingDevice = $wurflManager->getDeviceForHttpRequest($_SERVER);

?> 

<html> 
 <body> 

  <ul> 
   <li>ID: 
    <?php echo $requestingDevice->id; ?> </li> 
     <li>Brand Name: 
          <?php echo $requestingDevice->getCapability("brand_name"); ?> </li> 
     <li>Model Name: 
          <?php echo $requestingDevice->getCapability("model_name"); ?> </li> 
     <li>Resolution Width: 
          <?php echo $requestingDevice->getCapability("resolution_width"); ?> </li> 
     <li>Resolution Height: 
          <?php echo $requestingDevice->getCapability("resolution_height"); ?> </li> 
     <li>PDF Support: 
          <?php echo $requestingDevice->getCapability("pdf_support"); ?> </li> 
     <li>Flash Support: 
          <?php echo $requestingDevice->getCapability("full_flash_support"); ?> </li> 
  </ul> 

 </body> 
</html>

When I load this page on my iPhone 4, I see the device ID, its make and model, screen information, and whether it supports PDF and Flash. Figure 1 shows the results.

Figure 1. Results of the example code on iPhone 4
Image showing the browser results in iPhone 4

From this example, you can see that retrieving the value of a capability for a device is as simple as calling the getCapability method with the appropriate capability name.


Conclusion

From this article, you can see that there's a lot of value in using the WURFL in your mobile site or application. Quickly and easily gathering information about a given device rather than investing hours of additional programming time and many additional lines of code for data that could otherwise have been impossible to retrieve is by far the most attractive part of this powerful DDR.

Part 2 of this article series will dig into the WURFL PHP API in more depth and provide examples of how you can put it to use in your mobile PHP development.

Resources

Learn

Get products and technologies

Discuss

  • Get involved in the developerWorks community. Connect with other developerWorks users while exploring the developer-driven blogs, forums, groups, and wikis.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Mobile development on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Mobile development, Open source, Web development
ArticleID=792080
ArticleTitle=Build device-aware mobile sites using PHP, JavaScript, and WURFL
publish-date=02072012