WURFL Microservice Client API for PHP

Note: This guide assumes that you have access to a running instance of the WURFL Microservice HTTP Server, either through ScientiaMobile's Docker Registry, the AWS Marketplace, the Azure Marketplace, or other distribution channels. The guide also assumes familiarity with Device Detection (WURFL) and WURFL Capabilities.

WURFL Capabilities

WURFL Capabilities: WURFL capabilities are device properties represented in WURFL. While users of the WURFL Microservice for Docker have access to the list of licensed capabilities, customers who obtained the product through one of the Marketplace will have access to the WURFL capability list, predefined for the product they have licensed. Please note that there are two types of capabilities supported in WURFL: Static and Virtual.

While the difference between the two is mostly immaterial for you as a user as far as their practical usage goes, you still need to use two separate methods to use one or the other.

WURFL Microservice Client API (wmclient): Given an HTTP Request and a capability, the WURFL Client will return the property value.

Note: While the wmclient is an API, it requires interaction with the WURFL Microservice server to work. This introduces some latency (hugely mitigated by a built-in caching layer). For this reason, ScientiaMobile does not refer to the WURFL Microservice Client (wmclient) as a "WURFL API". That name is reserved for the WURFL OnSite APIs.

Obtaining, Installing and Running the wmclient

In order to use the wmclient please follow these instructions:

  1. Obtain the package with the wmclient library from the WURFL repository, cloning the project in your preferred location.

  2. Install the wmclient package using Composer:

    composer install --no-dev --optimize-autoloader
  3. Edit examples/cli.php (in the package), modifying the create() call to include the public IP address of your AMI instance or Docker container service (e.g. replacing localhost with the IP address of your running AMI in AWS Marketplace, or the address of your Docker container service).

Note: There are multiple ways in which a service deployed through Docker can be exposed to the world around it. Please refer to your DevOps if in doubt of the actual address at which the service is running.

  1. Run the example below:
require_once __DIR__ . '/../vendor/autoload.php';

try {
    // First we need to create a WM client instance, to connect to our WM server API at the specified host and port.
    $wmClient = \ScientiaMobile\WMClient\WMClient::create("http", "localhost", "8080");
    // we are activating the caching option in WM client. In order to not use cache, you just to need to omit enableCache call
} catch (\Exception $e) {
    // problems such as network errors  or internal server problems
    echo $e->getMessage();

// We ask Wm server API for some Wm server info such as server API version and info about WURFL API and file used by WM server.
$serveInfo = $wmClient->getInfo();
echo "WM server information: " . PHP_EOL;
echo " - WM version: " . $serveInfo->wmVersion() . PHP_EOL;
echo " - WURFL API version: " . $serveInfo->wurflAPIVersion() . PHP_EOL;
echo " - WURFL file info: " . $serveInfo->wurflInfo() . PHP_EOL;
echo PHP_EOL;

// set the capabilities we want to receive from WM server
// Static capabilities
$wmClient->setRequestedStaticCapabilities(["model_name", "brand_name"]);
// Virtual capabilities
$wmClient->setRequestedVirtualCapabilities(["is_smartphone", "form_factor"]);

$ua = "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3";

// Perform a device detection calling WM server API
$deviceData = $wmClient->lookupUserAgent($ua);

if ($deviceData->error()) {
    echo "WM client returned an error: " . $deviceData->error() . PHP_EOL;

// Let's get the device capabilities and print some of them
echo "WURFL device id: " . $deviceData->capabilities("wurfl_id") . PHP_EOL;

// print brand & model (static capabilities)
echo "This device is a: " . $deviceData->capabilities("brand_name") . " " . $deviceData->capabilities("model_name") . PHP_EOL;

// check if device is a smartphone (a virtual capability)
if ($deviceData->capabilities("is_smartphone") === "true") {
    echo "This is a smartphone" . PHP_EOL;
} else {
    echo "This is not a smartphone" . PHP_EOL;

// Printing all received capabilities
echo PHP_EOL;
echo "All received capabilities:" . PHP_EOL;

foreach ($deviceData->getAllCapabilities() as $key => $value) {
    echo " - $key: $value" . PHP_EOL;

// Get all the device manufacturers, and print the first twenty
$limit = 20;

$deviceMakes = $wmClient->getAllDeviceMakes();

echo PHP_EOL;
echo "Print the first $limit Brand of " . count($deviceMakes) . PHP_EOL;

// Sort the device manufacturer names

for ($i = 0; $i < $limit; $i++) {
    echo " - " . $deviceMakes[$i] . PHP_EOL;

echo PHP_EOL;

// Now call the WM server to get all device model and marketing names produced by Apple
echo "Print all Model for the Apple Brand" . PHP_EOL;

$modelMktNames = $wmClient->getAllDevicesForMake("Apple");

// Sort $modelMktNames by their model name

foreach ($modelMktNames as $modelMktName) {
    echo " - " . $modelMktName->modelName() . " " . $modelMktName->marketingName() . PHP_EOL;

// Now call the WM server to get all operative system names
$oses = $wmClient->getAllOSes();

echo PHP_EOL;
echo "Print the list of OSes" . PHP_EOL;

// Sort and print all OS names

foreach ($oses as $os) {
    echo " - " . $os . PHP_EOL;

echo PHP_EOL;
// Let's call the WM server to get all version of the Android OS
echo "Print all versions for the Android OS" . PHP_EOL;

$versions = $wmClient->getAllVersionsForOS("Android");

// Sort all Android version numbers and print them.

foreach ($versions as $version) {
    echo " - " . $version . PHP_EOL;

If you are using device detection from code running as part of an HTTP server, it is highly recommended that you pass the complete HTTP request to the lookupRequest method as follows:

$deviceData = $wmClient->lookupRequest(\GuzzleHttp\Psr7\ServerRequest::fromGlobals());

This will provide optimal detection accuracy (see examples/web.php). For a complete reference of all static and virtual capabilities, you can refer to this document. Please note that WURFL Microservice for the AWS Marketplace comes with a predefined set of capabilities.

Complete reference of the wmclient API

  • __construct: WMClient constructor
__construct(HttpClientInterface $client)
  • create: creates the WM Client using the default GuzzleHttpClient
static WMClient create(string $scheme, string $host, int $port, string $path = '')
  • getInfo: returns information about the running WM server and API
JsonInfoData getInfo()
  • lookupDeviceID: searches WURFL device data using its wurfl_id value
JsonDeviceData lookupDeviceID(string $deviceId)
  • lookupUserAgent: searches WURFL device data using the given user-agent for detection
JsonDeviceData lookupUserAgent(string $userAgent)
  • lookupRequest: detects a device from a request
JsonDeviceData lookupRequest(RequestInterface $request)
  • hasVirtualCapability: checks if the given $capabilityName exists in the clients virtual capability set
bool hasVirtualCapability(string $capabilityName)
  • hasStaticCapability: checks if the given $capabilityName exists in the clients static capability set
bool hasStaticCapability(string $capabilityName)
  • setRequestedCapabilities: sets the given capability names to the set they belong to
setRequestedCapabilities(array $capabilitiesList)
  • setRequestedVirtualCapabilities: sets a list of virtual capabilities to return
setRequestedVirtualCapabilities(array $virtualCapabilitiesList)
  • setRequestedStaticCapabilities: sets a list of static capabilities to return
setRequestedStaticCapabilities(array $staticCapabilitiesList)
  • enableCache: enables cache; if no ttl is supplied (or if the ttl is 0), the items will persist until the cache is cleared manually - otherwise, fails to exist in the cache (clear, restart, etc.)
enableCache(null|int $ttl = null)
  • clearCache: wipes the client cache clean
  • getApiVersion: returns the API version
string getApiVersion()

Error in case of Missing Capabilities

As mentioned above, depending on the configuration of your WURFL Microservice, one or more WURFL capabilities may be unavailable. In this case, the JSONDeviceData.Capabilities map will not contain an entry for those capabilities and the caller will get a return value of zero for it (nil).

Presence of a capability can be checked with:

value, ok := JSONDeviceData.Capabilities["has_cellular_radio"]

And check for:

ok = true/false

Additional capabilities can always be obtained by upgrading to greater version of the AMIs in the AWS Marketplace or by contacting ScientiaMobile to license additional capabilities for the Docker Image or other products.

© 2024 ScientiaMobile Inc.
All Rights Reserved.

NOTICE: All information contained herein is, and remains the property of ScientiaMobile Incorporated and its suppliers, if any. The intellectual and technical concepts contained herein are proprietary to ScientiaMobile Incorporated and its suppliers and may be covered by U.S. and Foreign Patents, patents in process, and are protected by trade secret or copyright law. Dissemination of this information or reproduction of this material is strictly forbidden unless prior written permission is obtained from ScientiaMobile Incorporated.