PHP Classes
elePHPant
Icontem

WURFL PHP Library: Get mobile device capabilities from WURFL files

Recommend this page to a friend!
  Info   View files View files (6)   DownloadInstall with Composer Download .zip   Reputation   Support forum (1)   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2005-05-20 (11 years ago) RSS 2.0 feedNot enough user ratingsTotal: 1,048 This week: 1All time: 3,406 This week: 1,047Up
Version License Categories
wurfl_class 1.0Unspecified (ask ...Wireless and Mobile
Description Author

This class can parse WURLF XML files to lookup for the capabilities of mobile device given its user agent string.

The class can extract several types of details about a given mobile device, like the supported GUI extensions, whether it supports WAP, ring tone support, etc..

The class can parse a WURFL file and cache its information to avoid the parsing overhead next time the information is looked up.

Picture of Andrea Trasatti
Name: Andrea Trasatti <contact>
Classes: 1 package by
Country: Italy Italy

Details
All the software described here was developed by Andrea Trasatti and is being
distributed for free to be use with WURFL.
Multicache implementation by Herouth Maoz ( herouth AT spamcop DOT net )
If you have comments or requests, don't hesitate to contact me:
atrasatti AT users DOT sourceforge DOT net

================
Revision history
================

V2.1 Beta2
- new search algorithm for unknown user agents, much faster
- added wurfl_config.php for cleaner configuration parameters
- added check_wurfl.php as a sample script to make sure everything is ok and
	read info about a device
- added update_cache.php, new script to create a new cache file (cache.php
	or multicache) so that you can force cache updates in production 
	environments and avoid automatic refresh which might cause problems on 
	sites with high traffic
- fixed a bug in case cache was set to false and WURFL_AUTOLOAD to true
- log levels are now supported appropriately

V2.1 Beta
- new licence (MPL 1.1)
- multicache

V2.0
- new license (BSD)
- better cache

=============
WARNING
=============
The current wurfl_class.php IS NOT compatible with the web patch.
From the very beginning the wurfl_class had a little check for a set of strings
in the user agent. If found, the browser is considered a WEB browser and the
class doesn't even search for it in WURFL. This was useful (and gives better
performances) for the 'browser_is_wap' property.
This is will be configurable in future versions.
A temporary solution could be to remove the check and let the class search for
the web browser. WURFL has a few defaul browsers and if the "web patch" is 
applied you will have a good number of web browsers recognized properly.

=============
WURFL parser
=============

This is a VERY simple PHP script to demonstrate how you could parse the WURFL
and have an associative array. Once you have the array you can obtain all the
data you need. You will certanly need some filters and take in consideration,
mainly, the fall_back feature. It's not natively implemented here, that is to
say, if you don't know a phone's feature and it's not listed in its
characteristics, you (read "your software") will need to search in its
parent.

2 caching systems are available. "classic" cache generates a file called
cache.php (you can change it in your config) which stored the entire associative
array serialized (old PHP versions) or using var_export (PHP 4.3.4 and above).
New "multicache" allows you to store only basic info in cache.php and generating
many tiny files in a specific directory. This should provide much faster access
times when reading the capabilities of a new device.
NOTE: if wurfl's mtime is older than the one stored in the cache file I
will not update the cache.

Defines used by this library:
WURFL_CONFIG      boolean, means you really configured the lib, otherwise quit
WURFL_FILE        string, Full path and filename of wurfl.xml
WURFL_USE_CACHE   boolean, true if I want to use a cache file
CACHE_FILE        string, with full path and filename of the cache file to
                  use
MULTICACHE_DIR    string, used only if you enabled Multicache, defines where
                  the cache files will be stored. WARNING: while cache.php will
                  grow in size but remain a single file, here the files will
                  grow in number. Expect more than 5000 tiny files.
MULTICACHE_SUFFIX string, suffix for the files generated using Multicache.
                  Useful if you use a caching system and don't want to load your
                  shared memory with a ton of tiny files.
WURFL_CACHE_AUTOUPDATE  boolean, tells the class to automatically update the
                        cached files with a new XML is found. This is NOT
                        suggested when using MULICACHE because of the high
                        number of files to be updated.  Race conditions are
                        highly possible to happen.

WURFL_PATCH_FILE  string, optional patch file for WURFL
WURFL_AGENT2ID_FILE  string, used by wurfl_class.php. needs to be removed
                     when a new WURFL is found

WURFL_LOG_FILE    string, defines full path and filename for logging
WURFL_AUTOLOAD    boolean, true if you want the XML to be loaded at every
                  startup. If not, the XML will be loaded when needed.
LOG_LEVEL         integer, desired logging level. Use the same constants
                  as for PHP logging

Logging. Logging is not really part of the tasks of this library. I included
basic logging just to survive BIG configuration mistakes. Warnings and
errors will be logged to the WURFL_LOG_FILE or, if not present, in the
webserver's log file using the error_log function.
Really bad events such as a wrong XML file, missing WURFL and a few more
will still generate a die() along with a log to file.
Someone might also want to send an e-mail or something, but this is WAY
ahead of the scope of this script.


=============
WURFL class
=============

This script is intended to help you to access data stored in WURFL. The class
works on an array generated by the WURFL parser. You may implement your own
parser emulating the same data structure if you'd like.

To configure the class you will need to adapt the following defines to your
environment:

WURFL_CONFIG		used in other libraries if the configuration was done
DATADIR           Where all data is stored (wurfl.xml, cache file, logs, etc)
WURFL_FILE        string, Full path and filename of wurfl.xml
WURFL_USE_CACHE   boolean, true if you want to use a cache file (strongly
                  suggested)
CACHE_FILE        string, with full path and filename of
                  the cache file to use (refreshed when a new WURFL is found)
WURFL_PATCH_FILE  string, optional patch file for WURFL
WURFL_AGENT2ID_FILE   string, used by wurfl_class.php. Is refreshed when a new
                      WURFL is found
WURFL_LOG_FILE    string, defines full path and filename for logging
WURFL_AUTOLOAD    boolean, true if you want the XML to be loaded at every
                  startup. If not, the XML will be loaded when needed.
MAX_UA_CACHE      int, set the maximum number of user_agents to cache in agent2id
LOG_LEVEL         int, sets the logging level. Use default PHP logging defines

The class loads the parser automatically. Use WURFL_PARSER_FILE as a define to
store the full path and filename. If not defined, the class will try to load the
parser in the local directory.

The class is initialized calling the constructor, wurfl_class and passing two
variables that may be empty. The former is the full XML parsed (like the parser
does) and the latter is the array of user agents and id's as generated by the
parser. Pass two empty variables if you want them to be filled (when needed) or
the real values if you already have them. The class will check the values and
the cache files and decide what to do. Also check your configuration, because
the behaviour will change.

Use the public method GetDeviceCapabilitiesFromAgent() passing the user agent
to make the class search for the best fit and fill the object's properties.
Once again, what the class does depends on your configuration, if you enabled
cache files and so on.
Once you have instantiated the object and passed a user agent you may use all
the class' methods.
Here is a list of properties:

$wurfl_class->_wurfl          is the WURFL array (all of it)
$wurfl_class->_wurfl_agents   is the associative array made of the user agents
                              and unique id's
$wurfl_class->user_agent      the visitor's user agent
$wurfl_class->wurfl_agent     the WURFL's best fitting user agent
$wurfl_class->id              the corresponding id
$wurfl_class->GUI             true if the device supports Openwave's GUI
                              extensions
$wurfl_class->browser_is_wap  true if the device is WAP capable (web browsers
                              such as Opera are considered non-WAP 
                              even if they DO support WML)
$wurfl_class->capabilities    the array of device's capabilities

Note: PHP (up to version 4.3) does not have any distinction between private and
public methods. In the wurfl_class implementation, I named all private methods
with a leading underscore to distinguish them from public methods without the
underscore. If you are interested in knowing the details, just open the class,
there are beautiful JAVADOC comments for each variable and method.
These libraries don't require register_globals anymore (from version 2 and up),
but will not work with versions before 4.1.

wurfl_class($wurfl, $wurfl_agents)   is the constructor. Built to work
                                     best with the wurfl_parser.

GetDeviceCapabilitiesFromAgent($ua)  given a user agent it will search WURFL
                                     for the best fit

getDeviceCapability($capability)     given a capability it will tell you the
                                     value. Remember that capabilities might be
                                     string, integer or boolean.

Extra features in wurfl_class: after some tests we noticed that the biggest
bottleneck was the hunt for the unique id for unrecognized devices. The solution
was, once again, an extra caching system that would store the associations
between user agents and wurfl IDs. This is valuable when an unknown agent visits
your site and you need to seek the most similar one in all the agents listed in
WURFL. Once a new agent has visited your site, you have a direct referral to it
and there is no need to search for it again.
 
A logging method is implemented too. This function will log the class actions
and calls. This feature is used mostly for debugging. 

A little note about the method to find the device, I have implemented a simple
system to avoid searching for user agents that are web browsers. The check is
made in the method "GetDeviceCapabilitiesFromAgent", if you have a strange
user agent that is not being recognized properly, check the logs see if the
class *thinks* it's a web browser, if so, 99% it's that specific check. Change
it at your wish and maybe let me know.

================
wurfl_config.php
================
Use this file to configure the parameters needed. Change the ones you like,
defaults should be good for most users.
Make sure the webserver has the permissions needed.

================
update_cache.php
================
High load sites might like to use this script to update the cache and set the
WURFL_CACHE_AUTOUPDATE to false and force it when needed. This is especially
useful with the multicache to avoid race conditions.
A simple locking system is implemented.

================
check_wurfl.php
================
Use this script to make sure you have configured the library appropriately and
to read devices' capabilities, when you need to.

=============
NOTICE
=============

Due to the HIGH load of reading the cache.php file every time the system needs
to search for a new device it is HIGHLY reccomended to use a caching system
such as Zend Cache, APC Cache version 2, Turck cache or eAccelerator.
If you don't use a caching system it will take a LONG time to load the file
cache.php that currently grows up to more than 2MB!

If you don't want to use any PHP cache, multicache should work well without.

=============
Sample code
=============

A demo page:

<?php

require_once('./wurfl_config.php');
require_once(WURFL_CLASS_FILE);

// creating the WURFL object
$myDevice = new wurfl_class($wurfl, $wurfl_agents);
$myDevice->GetDeviceCapabilitiesFromAgent($_SERVER["HTTP_USER_AGENT"]);
if ( $myDevice->browser_is_wap ) {
  header("Content-Type: text/vnd.wap.wml");
  echo '<?xml version="1.0" encoding="ISO-8859-1"?>'."\n";
?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org//DTD//wml_1.1.xml">
<wml>
 <card>
  <p mode="nowrap">

<?php
  if ( $myDevice->getDeviceCapability('gif') ) {
    echo '<img src="logo.gif" alt="Global TEL" />'."\n";
  } else {
    echo '<img src="logo.wbmp" alt="Global TEL" />'."\n<br/>\n";
  }
?>

<a href="index.php">Home</a><br/>
 </p>
 </card>
</wml>

<?php
} else {
?>
<img src="logo.gif"><br><br>
Welcome Web browser.<br>
We are sorry, but we are only offering WAP services, at this time.<br>
<?php } ?>



More information can be found on the website or on the mailinglist wmlprogramming.
http://wurfl.sf.net/
http://groups.yahoo.com/group/wmlprogramming

$Id: readme.txt,v 1.5 2005/05/03 14:44:54 atrasatti Exp $
  Files folder image Files  
File Role Description
Accessible without login Plain text file check_wurfl.php Example test script to verify that everything is ok
Accessible without login Plain text file readme.txt Doc. Documentation and license
Accessible without login Plain text file update_cache.php Aux. Script to force cache update. Read the docs
Plain text file wurfl_class.php Class The main class file
Accessible without login Plain text file wurfl_config.php Conf. Configuration parameters
Accessible without login Plain text file wurfl_parser.php Aux. XML parser for WURFL

 Version Control Unique User Downloads Download Rankings  
 0%
Total:1,048
This week:1
All time:3,406
This week:1,047Up