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.
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.
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.
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
| Node | Description | Example 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"/>
|
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> |
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.
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 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> |
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();
|
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
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.
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.
Learn
-
Learn more at the WURFL project page and
WURFL help
documentation.
-
Read more about the PHP API in the WURFL
PHP API documentation.
-
If you discover a device that's not in the WURFL, you can
contribute device information
to the DDR.
-
The Open source zone
on developerWorks provides a wealth of how-to information on
open source tools and technologies.
- Check for mobile updates on the
developerWorks Mobile development blog.
- You'll find many more articles on mobile topics, including articles on Dojo Mobile on developerWorks.
- Stay current with developerWorks technical events and webcasts focused on a variety
of IBM products and IT industry topics.
- Attend a free developerWorks Live! briefing to get up-to-speed quickly on
IBM products and tools, as well as IT industry trends.
- Watch developerWorks on-demand demos ranging from product installation
and setup demos for beginners, to advanced functionality for experienced
developers.
- Follow developerWorks on
Twitter.
Get products and technologies
-
Download the latest WURFL
repository.
-
Download the latest
WURFL PHP API.
- Download and try
the IBM Mobile Technology Preview, a set of code samples and services
to help you get started building mobile applications that extend and
integrate into the enterprise. The preview includes a RESTful notification
service; PhoneGap, an open source framework for building hybrid mobile
apps; a lightweight WebSphere Application Server runtime; and sample code
to let you see how it all works.
-
IBM WebSphere Application Server Feature Pack for Web 2.0 and
Mobile includes the IBM Dojo 1.7 Toolkit, new mobile and rich
Internet application (RIA) building blocks, and a Dojo-based diagram
component. With accompanying Rational tools, the Feature Pack helps you
take WebSphere applications developed originally for desktop browsers and
adapt and deploy them to mobile devices.
-
Evaluate
IBM products in the way that suits you best: Download a product
trial, try a product online, use a product in a cloud environment, or
spend a few hours in the SOA Sandbox learning how to implement Service Oriented
Architecture efficiently.
Discuss
- Get involved in the developerWorks
community. Connect with other developerWorks users while exploring
the developer-driven blogs, forums, groups, and wikis.
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.




