Projects / Tera-WURFL


Tera-WURFL is a PHP class that can identify the capabilities of mobile devices using the standardized Wireless Universal Resource File (WURFL). This implementation uses the same methods as the stock PHP WURFL library, but significantly improves performance by storing the WURFL data in a database backend (currently only MySQL). You can use multiple patch files to override the capabilities in the WURFL file. Tera-WURFL is able to figure out if the client visiting your site is a wireless device or a desktop Web browser. Unlike other implementations of WURFL, Tera-WURFL includes an easy-to-use graphical user interface to allow you to update your WURFL file directly from the Internet, load the WURFL file, browse and clear the device cache, and more.

Operating Systems

Recent releases

  •  19 Sep 2010 00:43

    Release Notes: This version introduces a MongoDB database connector, better support for Microsoft SQL Server and higher performance in MySQL. Also in this version, there is a full-featured command line interface for administering your system from the shell or scripts.

    •  04 Mar 2010 00:19

      Release Notes: This release brings more performance and better accuracy than the previous release by improving the UserAgentMatchers and SimpleDesktop Matching algorithms. It also adds support for Firefox Mobile and improves detection of Opera desktop Web browsers. There are a few new features, including a full-featured remote webservice with remote clients in PHP, Perl, Python, JavaScript, and ActionScript, a smarter installation page, and a form on the Web Administration Page which lets you submit incorrectly-detected user agents straight to the Tera-WURFL development team.

      •  10 Feb 2010 14:37

        Release Notes: A SimpleDesktop Matching Engine was introduced, which increases detection speed for desktop browsers by 10 times compared to version 2.0.0, while reducing the cache size by caching all desktop user agents in a single cache entry. Capability Filtering was introduced, which allows you to increase performance and drastically cut the size of your database. Capability Filtering lets you decide which capabilities you want to use from the WURFL file and ignores the rest. A bug that was preventing Firefox from being detected properly in some situations was fixed.

        •  15 Nov 2009 00:13

          Release Notes: The changes from version 2.0.0 RC5 include a MySQL4 database connector, an improved MySQL5 database connector, and various grammatical and spelling corrections.

          •  05 Nov 2009 20:56

            Release Notes: This is a complete code rewrite from the 1.x series. It takes much of the functionality for 2.x from an early pre-release of the Java WURFL Evolution project. It is currently more stable than 1.x and considerably more accurate. The 2.x branch includes specific User Agent Matchers that apply specific detection methods to specific groups of devices (i.e. Samsung, Apple, Nokia, and Firefox).

            Recent comments

            15 Nov 2009 00:34 kamermans

            Tera-WURFL 2.0 is out! With a faster and more accurate detection engine, Tera-WURFL 2.0 will empower your websites by differentiating between mobile and desktop browsers, small and large screens, compatible ringtones, video formats, streaming vs. download, and much more! Based on a prerelease of the Java WURFL Evolution, Tera-WURFL 2.0 uses UserAgentMatchers to apply specific detection methods to specific User Agents; for example, Nokia devices use the Nokia UserAgentMatcher.

            31 Oct 2006 18:31 kamermans

            PHP5 + MySQL5 Version
            I've been playing around with MySQL 5's Stored Procedures a bit, and I completely implemented the searching section of $obj->getDeviceCapabilitesFromAgent method in 1 stored procedure. This one is a mouthfull but could speed things up significantly!

            CREATE PROCEDURE `findUserAgent`(IN minlen INT, IN ua VARCHAR(128), IN preferroot TINYINT)


            DECLARE curlen INT;

            DECLARE prematch VARCHAR(45) DEFAULT NULL;

            DECLARE matches INT DEFAULT 0;

            DECLARE maxmatch INT DEFAULT 0;

            /* Look for an exact match first */

            SELECT deviceID INTO prematch FROM tera_wurfl_hybrid WHERE user_agent=ua LIMIT 1;

            IF prematch IS NOT NULL


            /* Found an exact match - done. */

            SELECT "Matched Exactly" AS match_type;

            SELECT * FROM tera_wurfl_hybrid WHERE deviceID=prematch;

            LEAVE findua;

            END IF;

            /* See if there is ever going to be a match */

            SELECT COUNT(user_agent) INTO maxmatch FROM tera_wurfl_hybrid WHERE user_agent LIKE (CONCAT(LEFT(ua,minlen),'%'));

            IF maxmatch = 0


            /* No matches were found, even down to the smallest char length - we don't need to continue */

            SELECT "Will Never Match" AS match_type;

            LEAVE findua;

            END IF;

            /* We've already tested the full length and the smallest length, so don't test them again */

            SELECT LEFT(ua, curlen - 1 ) INTO ua;

            SET minlen = minlen + 1;

            SELECT CHAR_LENGTH(ua) INTO curlen;

            WHILE ( curlen > minlen AND matches = 0) DO

            SELECT COUNT(user_agent) INTO matches FROM tera_wurfl_hybrid WHERE user_agent LIKE CONCAT(ua,'%');

            IF matches > 0 AND curlen > minlen


            SELECT "Matched After Trimming" AS match_type;

            IF preferroot = 1


            /* We would prefer a device root if there are multiple matching user agents */

            SELECT * FROM tera_wurfl_hybrid WHERE user_agent LIKE CONCAT(ua,'%') ORDER BY actual_device_root DESC LIMIT 1;

            LEAVE findua;


            /* We could really through a 'ORDER BY RAND() ' in there if we wanted to get creative */

            SELECT * FROM tera_wurfl_hybrid WHERE user_agent LIKE CONCAT(ua,'%') ORDER BY actual_device_root ASC LIMIT 1;

            LEAVE findua;

            END IF;

            END IF;

            SELECT LEFT(ua, curlen - 1 ) INTO ua;

            SELECT CHAR_LENGTH(ua) INTO curlen;

            END WHILE;

            /*SELECT "done" AS `status`;*/

            SELECT "Did Not Match" AS match_type;


            I may branch off the main PHP4+MySQL4 version and make a new version using this method since it's so fast.

            This is auto formatted very poorly so if you want a copy of it in a different form let me know.


            Project Spotlight


            A Fluent OpenStack client API for Java.


            Project Spotlight

            TurnKey TWiki Appliance

            A TWiki appliance that is easy to use and lightweight.