What's Covered
This tutorial illustrates how to use the API in a Web project. The following aspects are covered:
- Import detector settings from php.ini file
- Create an instance of Provider
- Print a table of details relating to the data set
- Process a match for requests User-Agent HTTP header and print a table of properties
- Process a match for requests relevant headers and print a table of properties
Code and Explanation
if (extension_loaded(FiftyOneDegreesPatternV3)) { require("../pattern/FiftyOneDegreesPatternV3.php"); $provider = FiftyOneDegreesPatternV3::provider_get(); } elseif (extension_loaded(FiftyOneDegreesTrieV3)) { require("../trie/FiftyOneDegreesTrieV3.php"); $provider = FiftyOneDegreesTrieV3::provider_get(); } else { echo "No 51Degrees PHP detector module found!<br>\n Please install and add entry to your php.ini file<br>\n"; } // List of all relevant HTTP headers $allHttpHeaders_in = $provider->getHttpHeaders(); for($i=0;$i<$allHttpHeaders_in->size();$i++) { $allHttpHeaders[$i] = $allHttpHeaders_in->get($i); } // Information about data set. // Determine if Pattern or Trie detector is used. $isPattern = True; $algorithmUsed = "Pattern"; if (strpos($provider->getDataSetName(), 'Trie') !== false) { $isPattern = FALSE; $algorithmUsed = "Trie"; } // List of properties as declared in PHP.ini file. // List may be different to properties contained in the initialised data set. // Some properties may not be in the data set you are trying to use. // I.e. Lite data set does not contain properties like IsTablet or DeviceType. if ($isPattern) { $iniProperties = ini_get('FiftyOneDegreesPatternV3.property_list'); $properties = explode(",", $iniProperties); } elseif ($algorithmUsed == "Trie") { $iniProperties = ini_get('FiftyOneDegreesTrieV3.property_list'); $properties = explode(",", $iniProperties); } if ($properties[1] == null) { $properties_in = $provider->getAvailableProperties(); for ($i=0;$i<$properties_in->size();$i++) { $properties[$i] = $properties_in->get($i); } } // 51Degrees Logo image link. $logoImage = getWebsiteLink("image", $isPattern); ?> <!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="https://51degrees.com/Demos/examples.css" class="inline"/> </head> <body> <div class="content"> <p> <img src="<?=$logoImage; ?>" alt="51Degrees logo image for PHP C Extension."/> </p> <h1>PHP <?=$algorithmUsed; ?> - Device Detection Example</h1> <?php printInfoTable($provider, $isPattern); printHttpHeaders($allHttpHeaders, "User-Agent", array("HTTP_USER_AGENT")); $match_ua = $provider->getMatch($_SERVER['HTTP_USER_AGENT']); printArrayToTable($match_ua, $properties, $isPattern, "ua"); printHttpHeaders($allHttpHeaders, "HTTP Headers"); $httpHeaders = ""; //Get all HTTP headers from $_SERVER foreach ($_SERVER as $key => $value) { if (strpos($key, "HTTP_") !== false) { $httpHeaders = $httpHeaders.$key." ".$value."\n"; } } $result_1 = $provider->getMatch($httpHeaders); printArrayToTable($result_1, $properties, $isPattern, 2); /** * Function prints the contents of a supplied array as a table. * @param $array is the array to print out. Mandatory. * @param $colNames a one dimensional array that contains names of columns. Optional. * Default values will be used if parameter not provided. */ function printArrayToTable($match, $properties, $isPattern, $occurance, $colNames=array("Property","Value","Data Type")) { // Columns in the array. $columnsInTable = count($colNames); // Extra column for the button. $columnsInArrayWithButton = $columnsInTable + 1; // Number of rows for properties. // Id, Rank, Method and Difference are not displayed in the properties // section, so we need less rows. // Default is for Trie and Trie only provides Id. $propertiesRows = count($properties) + 2; // Number of Match Metrics rows. Pattern provides more metrics stats. $metricsRowspan = 2; if ($isPattern) { // Pattern provides more metrics than Trie, hence more rows. $metricsRowspan = 5; } echo "<table>"; echo "<tbody>"; // Print metrics section. echo "<tr>"; echo "<th colspan='".$columnsInTable."'>Match Metrics</th>"; // Print 'About metrics' button. echo "<th rowspan='".$metricsRowspan."'>"; $link = getWebsiteLink("metrics", $isPattern, $occurance); echo "<a class='button' target='_blank' href='".$link."'>About Metrics</a>"; echo "</th>"; echo "</tr>"; //Print device Id. echo "<tr>"; echo "<td>Id</td>"; if (NULL !== $match->getDeviceId()) { //For Trie Id is an optional property. May not necessarily be set. echo "<td>".$match->getDeviceId()."</td>"; echo "<td>".gettype($match->getDeviceId())."</td>"; } else { echo "<td>N/A</td>"; echo "<td>N/A</td>"; } echo "</tr>"; if ($isPattern) { //Print detection method. echo "<tr>"; echo "<td>Method</td>"; echo "<td>".$match->getMethod()."</td>"; echo "<td>".gettype($match->getMethod())."</td>"; echo "</tr>"; //Difference. echo "<tr>"; echo "<td>Difference</td>"; echo "<td>".$match->getDifference()."</td>"; echo "<td>".gettype($match->getDifference())."</td>"; echo "</tr>"; //Rank. echo "<tr>"; echo "<td>Rank</td>"; echo "<td>".$match->getRank()."</td>"; echo "<td>".gettype($match->getRank())."</td>"; echo "</tr>"; } //Print column names //Print Device properties header echo "<tr>"; echo "<th colspan='".$columnsInTable."'>Device Properties</th>"; echo "<th rowspan='".$propertiesRows."'>"; $link = getWebsiteLink("properties", $isPattern, $occurance); echo "<a class='button' target='_blank' href='".$link."'>More Properties</a>"; echo "</th>"; echo "</tr>"; echo "<tr>"; foreach($colNames as $key) { echo "<td>$key</td>"; } echo "</tr>"; //Print table contents. if ($properties != NULL) { //Dataset was in fact initialised with a list of properties. foreach($properties as $value) { //Ignore Rank, Id, Method and Difference as they are printed elsewhere. if ($value === "SignatureRank" || $value === "Rank" || $value === "Difference" || $value === "Method" || $value ==="Id") { continue; } echo "<tr>"; echo "<td><a href='https://51degrees.com/resources/property-dictionary#$value'>$value</a></td>"; if ($match->getValue($value) != NULL) { echo "<td>".$match->getValue($value)."</td>"; } else { echo "<td><a href='https://51degrees.com/compare-data-options'>Switch Data Set</a></td>"; } echo "<td>".gettype($match->getValue($value))."</td>"; echo "</tr>"; } } else { //NULL was provided, meaning all properties selected. foreach($match->getAvailableProperties() as $key => $value) { //Ignore Rank, Id, Method and Difference as they are printed elsewhere. if ($key === "SignatureRank" || $key === "Rank" || $key === "Difference" || $key === "Method" || $key ==="Id") { continue; } echo "<tr>"; echo "<td><a href='https://51degrees.com/resources/property-dictionary#$key'>$key</a></td>"; echo "<td>".$value."</td>"; echo "<td>".gettype($value)."</td>"; echo "</tr>"; } } echo "</tbody>"; echo "</table>"; } /** * Function prints information related to the data file currently in use. */ function printInfoTable($provider, $isPattern) { //How many columns will be required. $columns = 3; echo "<table>"; echo "<tbody>"; echo "<tr>"; echo "<th colspan='$columns' class='fod_table_header'>Data Set Information</th>"; echo "</tr>"; //Print dataset initialisation message. //Third column spans all rows and is used to print 'Compare Data Options' button. if ($columns == 3) { echo "<td rowspan='6'>"; $link = getWebsiteLink("compare", $isPattern); echo "<a class='button' target='_blank' href='".$link."'>Compare Data Options</a>"; echo "</td>"; } echo "</tr>"; //Print dataset Published date. Pattern only. echo "<tr>"; echo "<td>Dataset published:</td>"; if ($isPattern) { echo "<td>".$provider->getDataSetPublishedDate()."</td>"; } else { echo "<td>Not available for Trie.</td>"; } echo "</tr>"; //Print dataset next update date. Pattern only. echo "<tr>"; echo "<td>Dataset next update:</td>"; if ($isPattern) { echo "<td>".$provider->getDataSetNextUpdateDate()."</td>"; } else { echo "<td>Not available for Trie.</td>"; } echo "</tr>"; //Print dataset version. Pattern only. echo "<tr>"; echo "<td>Dataset version:</td>"; if ($isPattern) { echo "<td>".$provider->getDataSetFormat()."</td>"; } else { echo "<td>Not available for Trie.</td>"; } echo "</tr>"; //Print dataset name. Exists for both Pattern and Trie. Both Pattern and Trie. echo "<tr>"; echo "<td>Dataset name:</td>"; echo "<td>".$provider->getDataSetName()."</td>"; echo "</tr>"; //Print device combinations. Pattern only. echo "<tr>"; echo "<td>Dataset device combinations:</td>"; if ($isPattern) { echo "<td>".$provider->getDataSetDeviceCombinations()."</td>"; } else { echo "<td>Not available for Trie.</td>"; } echo "</tr>"; echo "</tbody>"; echo "</table>"; } /** * Function prints all relevant headers and values for the relevant HTTP * headers that were set in this request. */ function printHttpHeaders($array, $name, $headers=array()) { if (empty($array)) { return null; } $selective = FALSE; if(!empty($headers)) { $selective = TRUE; } echo "<table>"; echo "<tbody>"; echo "<tr>"; echo "<th colspan='2'>Match With $name</th>"; echo "</tr>"; foreach ($array as $value) { if ($selective) { //Only some headers are required. //If current header not in the array of required headers skip. if (!in_array("HTTP_".strtoupper(str_replace("-","_",$value)), $headers)) { continue; } } echo "<tr>"; echo "<td>"; echo $value; echo "</td>"; echo "<td>"; if ($_SERVER["HTTP_".strtoupper(str_replace("-","_",$value))] != NULL) { echo $_SERVER["HTTP_".strtoupper(str_replace("-","_",$value))]; } else { echo "<i>header not set</i>"; } echo "</td>"; echo "</tr>"; } echo "</tbody>"; echo "</table>"; } /** * Function generates a link to 51Degrees based on the purpose of the link, whether * the detector is operating in Pattern or Trie modes and if the link is created for * the match with User-Agent function or the Match with Headers function. Guaranteed * to return a link, even if the parameter is not known. * @returns a link to 51Degrees.com */ function getWebsiteLink($purpose, $isPattern, $occurance=1) { $url = "https://51degrees.com"; $utmSource = "utm_source=Github"; $utmMedium = "utm_medium=repository"; $utmContent = "example_trie"; if($isPattern) { $utmContent = "example_pattern"; } $utmCampaign = "utm_campaign=php-open-source"; if ($purpose === 'image') { $url = "https://51degrees.com/DesktopModules/FiftyOne/Distributor/Logo.ashx"; } else if ($purpose === 'metrics') { $url = "https://51degrees.com/support/documentation/howdevicedetectionworks/trie"; if ($isPattern) { $url = "https://51degrees.com/support/documentation/pattern"; } if ($occurance == 2) { $utmContent .= "_header"; } else { $utmContent .= "_ua"; } } else if ($purpose === 'compare') { $url = "https://51degrees.com/compare-data-options"; $utmContent .= "_compare"; } else if ($purpose === 'properties') { $url = "https://51degrees.com/resources/property-dictionary"; if ($occurance == 2) { $utmContent .= "_properties_header"; } else { $utmContent .= "_properties_ua"; } } return $url."?".$utmSource."&".$utmMedium."&".$utmContent."&".$utmCampaign; }
Summary
In this tutorial you have seen how to use the detector in the context of a simple server to retrieve various properties from both a single User-Agent header and multiple HTTP headers. For a full list of properties and the data files they exist in please see the
Property Dictionary
.