Popular Topics

The DeviceAtlas API in PHP – Part I (The Basics)

March 7, 2008, by

Shareshare-arrow

UPDATED… AGAIN… 10/02/2009

We have just released version 2.3 of our API as a Beta with a whole host of new features that make integrating it into any PHP website much much easier. The download comes with extensive samples and documentation to help you get started.Find out more…

The OO version of the API has been designed according to accepted OO patterns
and practices for PHP. All classes are "namespaced" (PHP style) under
Mobi_Mtld_DA. i.e. The API class is called Mobi_Mtld_DA_Api.

A quick find-replace should be all that is needed to alter existing PHP code so
that it will use the new API.

Old Function

New Function

da_get_api_revision

Mobi_Mtld_DA_Api::getApiRevision

da_get_properties

Mobi_Mtld_DA_Api::getProperties

da_get_properties_as_typed

Mobi_Mtld_DA_Api::getPropertiesAsTyped

da_get_property

Mobi_Mtld_DA_Api::getProperty

da_get_property_as_boolean

Mobi_Mtld_DA_Api::getPropertyAsBoolean

da_get_property_as_date

Mobi_Mtld_DA_Api::getPropertyAsDate

da_get_property_as_integer

Mobi_Mtld_DA_Api::getPropertyAsInteger

da_get_property_as_string

Mobi_Mtld_DA_Api::getPropertyAsString

da_get_tree_from_file

Mobi_Mtld_DA_Api::getTreeFromFile

da_get_tree_from_string

Mobi_Mtld_DA_Api::getTreeFromString

da_get_tree_revision

Mobi_Mtld_DA_Api::getTreeRevision

da_list_properties

Mobi_Mtld_DA_Api::listProperties

The new API also uses PHP exceptions to catch common coding errors. More details
about the exceptions and when they are thrown is available in the documentation.

DeviceAtlas is the world's most comprehensive database of mobile device information. The database comes with an API that developers can use to determine the capabilities of devices browsing their website and in so doing adapt their content to make it suitable for the user’s context.

Part I of this tutorial will assist PHP developers in learning the basics of the API and how to use it.

Background

In order to provide relevant content to users on mobile devices content providers are forced to adapt their content to suit the capabilities of the user's device. In order to do this the content provider must analyse the request sent by the user to try and determine what device they are actually using.

All devices, when connecting to a content provider will send a number of headers with details about the web browser being used, the character encoding they support, the MIME types they can handle and more. Unfortunately the information provided in these headers is often incomplete, inconsistent or even modified by proxies along the way so that the content provider faces an ever more complex task determining what device is trying to access their content.

The most effective clue in determining a user's device is the "User Agent" header. The DeviceAtlas API uses this header to query its extensive database of devices and to give the content provider details about any capabilities or limitations of the user's device. The provider can then be sure they are delivering content that will be accessable and usable for that specific device.

Introduction

Part I of this tutorial will introduce developers to DeviceAtlas and the DeviceAtlas API. It will demonstrate how a PHP developer may use the API in delivering adapted content to their users.

DeviceAtlas simply provides the database of devices and functions to query this database with a "User Agent" string. Functionality such as caching the database and "sniffing" out the user agent string in unusual circumstances is left to the developer.

Part I of the tutorial will ignore these for now however Part II will focus on addressing those extra aspects of a DeviceAtlas implementation and make suggestions about how these tasks may be tackled.

Target

Any level of PHP developer comfortable with the basics of the language can use this tutorial. It is suggested that users be familiar with HTML and if possible XHTML-MP and CSS.

System Requirements

To complete the tutorial you will need a web server (local or remote) with a recent version of PHP installed. (Version 5.2.3 is a minimum requirement. The DeviceAtlas data is stored as a json file and older versions are unable to recurse deep enough to load the data). I am using Apache 2.2.4 with PHP 5.2.5 on Windows XP.

Using DeviceAtlas on older versions of PHP may be possible with some hacks however that is outside the scope of this tutorial, perhaps another day.

Time

Part I of the tutorial will take between 5 and 20 minutes depending on your level of competence with PHP. Advanced PHP developers will be able to skim over this tutorial and will most likely find the example code quite self-explanatory.

File Structure

Download the latest PHP version of the DeviceAtlas API (You will need to be logged in. Use your dev.mobi account or create one. It's free!).

doc contains the phpDoc for the API which is a useful reference for the functions offered by the API.

sample contains a basic sample of the API in use and a developer version of the json database (Identical structure to the live data but may not be up to date.) The sample contains some more advanced functionality covered in Part II of the tutorial.

The two files in
/Mobi/Mtld/DA are Api.php the source code of the API and Test.php a command-line script for testing the json database.

To get started I also created a file called index.php in the root and created a folder called json where I have placed a copy of DeviceAtlas.json
(the latest data downloaded from the website)so the project directory now looks like this:

You can set the directory structure out however you like, the important files we need are index.php,DeviceAtlas.json and the folder Mobi
and its contents.

index.php will form the root of the project which will include API functions from
Api.php and load the device database from DeviceAtlas.json.

Tutorial

Step 1

We begin by editing index.php. All we want for now is a basic html page that says "Hello World". Insert the following lines.:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?php

header("Cache-Control: max-age=200 ");

header("Content-Type: application/xhtml+xml");

echo'<?xml version="1.0"encoding="utf-8"?>';

?>

<!DOCTYPE html PUBLIC"-//WAPFORUM//DTD XHTML Mobile 1.2//EN"

"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>Hello Mobile World</title>

</head>

<body>

<p>Hello Mobile World!</p>

</body>

</html>

A very basic XHTML-MP page that simply sets the page title and displays the text "Hello World". I have uploaded the project to the web and tested it on ready.mobi. In the Nokia N70 Emulator the page looks like this:

Step 2

Not a very inspiring page so far and one that certainly won't need any changes for different screen sizes or device capabilities. But let's throw in a picture logo, some links and some styling to jazz it up a bit. The code now looks like this:

Not likely to win any style awards but contains many of the basic elements of a mobile web page.

Step 3

Now let's introduce DeviceAtlas. The first step is to include the API functions and load up the database of devices into a tree which we assign to the variable $tree. We do this by adding the following 2 lines to the PHP block at the top of the page.

1

2

require_once'Mobi/Mtld/DA/Api.php';

$tree=Mobi_Mtld_DA_Api::getTreeFromFile('json/DeviceAtlas.json');

The next step is to get the user agent header sent by the device so we can query the database. The user agent is usually stored in the server variable HTTP_USER_AGENT. This value is often inconsistent usually due to interference by proxies. There are ways to "sniff" out the correct user agent which are covered in Part II of this tutorial. For now we just assume the server variable is correct.

1

$ua=$_SERVER['HTTP_USER_AGENT'];

Now all of the API functions are available to us. Let's start using them by wowing our visitor and telling them what device they are using.

I have replaced our <h1>Hello Mobile World!</h1> with the following code:

1

2

3

4

5

6

7

8

<?php

try{

$vendor=Mobi_Mtld_DA_Api::getProperty($tree,$ua,'vendor');

}catch(Mobi_Mtld_Da_Exception_InvalidPropertyException$e){

$vendor="Unknown";

}

?>

<h1>Hello<?phpecho$vendor;?>user!</h1>

The result on the N70 emulator is:

Step 4

Notice we have determined the device manufacturer by using the Mobi_Mtld_DA_Api::getProperty function of the api.
If this property is unknown we catch the InvalidPropertyException and provide a
default.

But how did I know what value to put as the third argument, in this case vendor?

The beauty of the DeviceAtlas database is that it is constantly evolving. Over time we plan to increase the number of characteristics that are included for each device so it is impossible to publish a list of these properties that will be valid for all time.

The easiest way to get a list of available properties is to use the function Mobi_Mtld_DA_Api::listProperties. This will return an array of all the properties stored in your current version of the DeviceAtlas data. The latest version has a property called vendor which will contains the name of the device vendor.

Another useful function is Mobi_Mtld_DA_Api::getProperties which will return an array of all the properties available for this device. The array is indexed by the property names. For more info on the properties and functions in the API have a look at the API documentation that comes as part of the API download.

In the next snippet I have replaced the links and paragraphs with some new PHP code to loop through the properties and display them on screen:

The output is not very pretty but it gives you an idea of what DeviceAtlas can tell us about the device that is browsing our site.

Step 5

Finally Let's get back to our code from Step 3 and make some changes so that we can adjust our output dependant on the user's device capabilities. A slightly more practical use for DeviceAtlas than merely telling the user what device they are using!

Let's assume that our existing design will work for mid-range browsers. What about high end browsers like an iPhone or really low end browsers without image support?

First I will test for PNG support and decide if we want to display our image at all. Next I will check to see if the device screen is wide enough to use a bigger image. The resulting code looks like this:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

<?php

//Include API

require_once'Mobi/Mtld/DA/Api.php';

$tree=Mobi_Mtld_DA_Api::getTreeFromFile('json/DeviceAtlas.json');

$ua=$_SERVER['HTTP_USER_AGENT'];

header("Cache-Control: max-age=200 ");

header("Content-Type: application/xhtml+xml ");

echo'<?xml version="1.0"encoding="utf-8"?>';

?>

<!DOCTYPE html PUBLIC"-//WAPFORUM//DTD XHTML Mobile 1.2//EN"

"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>HelloMobileWorld</title>

<style type="text/css">

h1 {background-color:#000000;color:#ffffff;}

li {list-style:none;}

</style>

</head>

<body>

<?php

try{

$pngSupport=Mobi_Mtld_DA_Api::getProperty($tree,$ua,'image.Png');

}catch(Mobi_Mtld_Da_Exception_InvalidPropertyException$e){

$pngSupport=false;//You may wish to have some other fallback (like assuming true for unknown)

}

if($pngSupport)://Supports PNG images

try{

$displayWidth=Mobi_Mtld_DA_Api::getProperty($tree,$ua,'image.Png');

}catch(Mobi_Mtld_Da_Exception_InvalidPropertyException$e){

$displayWidth=128;//Default to 128 for unknown

}

if($displayWidth>=240){

$image='logo_239x107.png';

$width=239;

$height=107;

}else{

$image='logo_128x57.png';

$width=128;

$height=57;

}

?>

<p><img id="logo"src="img/<?phpecho$image;?>"

alt="dotMobi Logo"width="<?phpecho$width;?>"

height="<?phpecho$height;?>"/></p>

<?phpendif;?>

<hr/>

<?php

try{

$vendor=Mobi_Mtld_DA_Api::getProperty($tree,$ua,'vendor');

}catch(Mobi_Mtld_Da_Exception_InvalidPropertyException$e){

$vendor="Unknown";

}

?>

<h1>Hello<?phpecho$vendor;?>user!</h1>

<ul>

<li><ahref="index.php?page=1"accesskey="1">(1)Link1</a></li>

<li><ahref="index.php?page=2"accesskey="2">(2)Link2</a></li>

<li><ahref="index.php?page=3"accesskey="3">(3)Link3</a></li>

</ul>

<p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit.

Ineuismod miaurna.Inultrices turpis vitae nibh.</p>

<p>Sed sed ipsum id dolor nonummy dignissim.Nulla mi ante,

placerat nec,vestibulum sed,fringilla at,velit.</p>

<p>Nulla nonummy purus sed nisl.Mauris tincidunt urna sit amet dui.

Cras sem justo,mollis et,tincidunta,pellentesque eget,quam.

Vestibulum quis velit et erat dictum ultrices.

Praesent fermentum arcu nec sapien.Nunc eleifend.</p>

</body>

</html>

The output won't change when viewed on the emulator but if a user browsed this page from an older phone that couldn't dispaly PNG images I would exclude the image from my output altogether. Also if I am fortunate and the user has a nice big display I know I can take advantage of this and use a bigger image rather than have my image lost in the corner of the screen. st in the corner of the screen. corner of the screen.

What this very basic example demonstrates is how a developer may use DeviceAtlas to access the characteristics of a device and use these to determine how they choose to adapt their output.

The example above is extremly simplified and it is left to the developer to decide the best way to implement the DeviceAtlas API. The amount of content to adapt, the target audience and the specific needs of the website should all be considered in developing a content adaption strategy.

Tools like ready.mobi will help you to test your site as they simulate the headers of the phone the are emulating.

In Part II of the tutorial we will look at caching device data for better performance and "sniffing" out the correct user agent before querying the DeviceAtlas API to ensure more accurate results.

I’m new to this mobile development.
During my first exercise (in this tute) I got the following error,

XML Parsing Error: junk after document element
Location: http://localhost/mobile/
Line Number 2, Column 1:Warning: file_get_contents(json/DeviceAtlas.json) [function.file-get-contents]: failed to open stream: No such file or directory in C:\wamp\www\mobile\Mobi\Mtld\DA\Api.php on line 123
^

If any one knows why its appearing please help me to sort out this..
Also I’m using PHP and Apache higher versions than the minimum requirements.
If there is any specific extensions to be ON before we use the coding please let me know..
Please Help!
Thank you.
Isuru

[quote=auisuru]
Line Number 2, Column 1:Warning: file_get_contents(json/DeviceAtlas.json) [function.file-get-contents]: failed to open stream: No such file or directory in C:\wamp\www\mobile\Mobi\Mtld\DA\Api.php on line 123
[/quote]

Looks like you haven’t setup your script to load the JSON file from the correct path.
I’d suggest you use an absolute path to be sure it loads correctly.

my code seems to be overwhelmed by the size of the json file (16mb in size), and the code seems to halt. It works when I try to use the provided Sample.json which is much smaller in size. What should I do?

UPDATE:
I’ve traced the error to $tree = json_decode($json, true); in the function
getTreeFromString. I believe there is something wrong with my provided json file from DeviceAtlas.

This is a website of Afilias Technologies Ltd, a private company limited by shares, incorporated and registered in the Republic of Ireland with registered number 398040 and registered office at 6th Floor, 2 Grand Canal Square, Dublin 2, Ireland