From 1e747f83468203be2cb2565652e5e1f1d4fac53f Mon Sep 17 00:00:00 2001 From: "udger.com" Date: Sun, 21 Aug 2016 11:40:22 +0200 Subject: [PATCH 01/13] add device marketname --- src/Parser.php | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/src/Parser.php b/src/Parser.php index 5a5a5e9..831d002 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -199,6 +199,13 @@ public function parse() 'device_class_icon' => '', 'device_class_icon_big' => '', 'device_class_info_url' => '', + 'device_marketname' => '', + 'device_brand' => '', + 'device_brand_code' => '', + 'device_brand_homepage' => '', + 'device_brand_icon' => '', + 'device_brand_icon_big' => '', + 'device_brand_info_url' => '', 'crawler_last_seen' => '', 'crawler_category' => '', 'crawler_category_code' => '', @@ -375,9 +382,9 @@ public function parse() } if ($deviceclass_id == 0 AND $client_class_id != -1) { $q = $this->dbdat->query("SELECT deviceclass_id,name,name_code,icon,icon_big - FROM udger_deviceclass_list - JOIN udger_client_class ON udger_client_class.deviceclass_id=udger_deviceclass_list.id - WHERE udger_client_class.id=" . $client_class_id . " "); + FROM udger_deviceclass_list + JOIN udger_client_class ON udger_client_class.deviceclass_id=udger_deviceclass_list.id + WHERE udger_client_class.id=" . $client_class_id . " "); if ($r = $q->fetchArray(SQLITE3_ASSOC)) { $this->logger->debug("parse useragent string: device found by deviceclass"); $deviceclass_id = $r['deviceclass_id']; @@ -388,6 +395,39 @@ public function parse() $ret['user_agent']['device_class_info_url'] = "https://udger.com/resources/ua-list/device-detail?device=" . $r['name']; } } + + // device marketname + if($ret['user_agent']['os_family_code']) { + $q = $this->dbdat->query("SELECT id,regstring FROM udger_devicename_regex WHERE + ((os_family_code='".$ret['user_agent']['os_family_code']."' AND os_code='-all-') + OR + (os_family_code='".$ret['user_agent']['os_family_code']."' AND os_code='".$ret['user_agent']['os_code']."')) + order by sequence"); + while ($r = $q->fetchArray(SQLITE3_ASSOC)) { + @preg_match($r["regstring"],$this->ua,$result); + if($result[1]) { + $qC=$this->dbdat->query("SELECT marketname,brand_code,brand,brand_url,icon,icon_big + FROM udger_devicename_list + JOIN udger_devicename_brand ON udger_devicename_brand.id=udger_devicename_list.brand_id + WHERE regex_id=".$r["id"]." and code = '".trim($result[1])."' "); + + if($qC->numRows() > 0) { + $rC=$q->fetchArray(SQLITE3_ASSOC); + $this->logger->debug("parse useragent string: device marketname found"); + $ret['user_agent']['device_marketname'] = $rC['marketname']; + $ret['user_agent']['device_brand'] = $rC['brand']; + $ret['user_agent']['device_brand_code'] = $rC['brand_code']; + $ret['user_agent']['device_brand_homepage'] = $rC['brand_url']; + $ret['user_agent']['device_brand_icon'] = $rC['icon']; + $ret['user_agent']['device_brand_icon_big'] = $rC['icon_big']; + $ret['user_agent']['device_brand_info_url'] = "https://udger.com/resources/ua-list/devices-brand-detail?brand=".$rC['brand_code']; + + break; + } + } + } + } + } $this->logger->debug("parse useragent string: END, unset useragent string"); From 4296a2440e87522396a770df1f4c0d6595a674f5 Mon Sep 17 00:00:00 2001 From: "udger.com" Date: Sun, 21 Aug 2016 11:53:19 +0200 Subject: [PATCH 02/13] Add datacenter Ipv6 --- src/Helper/IP.php | 22 ++++++++++++++++++++++ src/Helper/IPInterface.php | 2 ++ src/Parser.php | 25 ++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/Helper/IP.php b/src/Helper/IP.php index 3037750..e199e96 100644 --- a/src/Helper/IP.php +++ b/src/Helper/IP.php @@ -39,4 +39,26 @@ public function getIpLong($ip) { return sprintf('%u', ip2long($ip)); } + + + /** + * Ipv6 to array + * + * @param string $ip + * @return array + */ + public function getIp6array($ip){ + // expand - example: "2600:3c00::" -> "2600:3c00:0000:0000:0000:0000:0000:0000" + $hex = unpack("H*hex", inet_pton($ip)); + $ipStr = substr(preg_replace("/([A-f0-9]{4})/", "$1:", $hex['hex']), 0, -1); + + $ipIntArray = array(); + $ipStrArray = split(":", $ipStr); + + foreach ($ipStrArray as &$value) { + $ipIntArray[] = hexdec($value); + } + + return $ipIntArray; + } } \ No newline at end of file diff --git a/src/Helper/IPInterface.php b/src/Helper/IPInterface.php index b92cac6..d5f0605 100644 --- a/src/Helper/IPInterface.php +++ b/src/Helper/IPInterface.php @@ -14,4 +14,6 @@ interface IPInterface { public function getIpVersion($ip); public function getIpLong($ip); + + public function getIp6array($ip); } diff --git a/src/Parser.php b/src/Parser.php index 831d002..b9a3b89 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -500,10 +500,33 @@ public function parse() $ret['ip_address']['datacenter_homepage'] = $r['homepage']; } } + else if ($this->ipHelper->getIpVersion($ret['ip_address']['ip_ver']) === IPInterface::IPv6) { + $ipInt = $this->ipHelper->getIp6array($ret['ip_address']['ip']); + + $this->dbdat->query("select name,name_code,homepage + FROM udger_datacenter_range6 + JOIN udger_datacenter_list ON udger_datacenter_range6.datacenter_id=udger_datacenter_list.id + where + iplong_from0 <= ".$ipInt[0]." AND iplong_to0 >= ".$ipInt[0]." AND + iplong_from1 <= ".$ipInt[1]." AND iplong_to1 >= ".$ipInt[1]." AND + iplong_from2 <= ".$ipInt[2]." AND iplong_to2 >= ".$ipInt[2]." AND + iplong_from3 <= ".$ipInt[3]." AND iplong_to3 >= ".$ipInt[3]." AND + iplong_from4 <= ".$ipInt[4]." AND iplong_to4 >= ".$ipInt[4]." AND + iplong_from5 <= ".$ipInt[5]." AND iplong_to5 >= ".$ipInt[5]." AND + iplong_from6 <= ".$ipInt[6]." AND iplong_to6 >= ".$ipInt[6]." AND + iplong_from7 <= ".$ipInt[7]." AND iplong_to7 >= ".$ipInt[7]." + "); + + if ($r = $q->fetchArray(SQLITE3_ASSOC)) { + $ret['ip_address']['datacenter_name'] = $r['name']; + $ret['ip_address']['datacenter_name_code'] = $r['name_code']; + $ret['ip_address']['datacenter_homepage'] = $r['homepage']; + } + } } $this->logger->debug("parse IP address: END, unset IP address"); - $this->ua = ''; + $this->ip = ''; } return $ret; } From 79fe9e56df25e78e442d3e14b5d1e4a59eba7a01 Mon Sep 17 00:00:00 2001 From: "udger.com" Date: Thu, 8 Sep 2016 17:23:25 +0200 Subject: [PATCH 03/13] fix datacenter6 error --- src/Parser.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Parser.php b/src/Parser.php index b9a3b89..b7b966b 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -404,15 +404,15 @@ public function parse() (os_family_code='".$ret['user_agent']['os_family_code']."' AND os_code='".$ret['user_agent']['os_code']."')) order by sequence"); while ($r = $q->fetchArray(SQLITE3_ASSOC)) { - @preg_match($r["regstring"],$this->ua,$result); + @preg_match($r["regstring"],$this->ua,$result); + if($result[1]) { $qC=$this->dbdat->query("SELECT marketname,brand_code,brand,brand_url,icon,icon_big FROM udger_devicename_list JOIN udger_devicename_brand ON udger_devicename_brand.id=udger_devicename_list.brand_id WHERE regex_id=".$r["id"]." and code = '".trim($result[1])."' "); - if($qC->numRows() > 0) { - $rC=$q->fetchArray(SQLITE3_ASSOC); + if($rC = $qC->fetchArray(SQLITE3_ASSOC)) { $this->logger->debug("parse useragent string: device marketname found"); $ret['user_agent']['device_marketname'] = $rC['marketname']; $ret['user_agent']['device_brand'] = $rC['brand']; @@ -499,11 +499,10 @@ public function parse() $ret['ip_address']['datacenter_name_code'] = $r['name_code']; $ret['ip_address']['datacenter_homepage'] = $r['homepage']; } - } - else if ($this->ipHelper->getIpVersion($ret['ip_address']['ip_ver']) === IPInterface::IPv6) { + } + else { $ipInt = $this->ipHelper->getIp6array($ret['ip_address']['ip']); - - $this->dbdat->query("select name,name_code,homepage + $q = $this->dbdat->query("select name,name_code,homepage FROM udger_datacenter_range6 JOIN udger_datacenter_list ON udger_datacenter_range6.datacenter_id=udger_datacenter_list.id where From c66038b23d2838830245d6a2ef16db8561d89cd7 Mon Sep 17 00:00:00 2001 From: "udger.com" Date: Thu, 8 Sep 2016 17:57:13 +0200 Subject: [PATCH 04/13] add escapeString --- src/Parser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Parser.php b/src/Parser.php index b7b966b..f71075e 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -256,7 +256,7 @@ public function parse() $q = $this->dbdat->query("SELECT udger_crawler_list.id as botid,name,ver,ver_major,last_seen,respect_robotstxt,family,family_code,family_homepage,family_icon,vendor,vendor_code,vendor_homepage,crawler_classification,crawler_classification_code FROM udger_crawler_list LEFT JOIN udger_crawler_class ON udger_crawler_class.id=udger_crawler_list.class_id - WHERE ua_string='" . $this->ua . "'"); + WHERE ua_string='" . $this->dbdat->escapeString($this->ua) . "'"); if ($r = $q->fetchArray(SQLITE3_ASSOC)) { $this->logger->debug("parse useragent string: crawler found"); From 82859351fba1568352bede0020f34d49f8280657 Mon Sep 17 00:00:00 2001 From: "udger.com" Date: Fri, 9 Sep 2016 15:58:52 +0200 Subject: [PATCH 05/13] fix datacenter6 error --- src/Parser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Parser.php b/src/Parser.php index f71075e..5698754 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -500,7 +500,7 @@ public function parse() $ret['ip_address']['datacenter_homepage'] = $r['homepage']; } } - else { + else if ($this->ipHelper->getIpVersion($ret['ip_address']['ip_ver']) === IPInterface::IPv6) { $ipInt = $this->ipHelper->getIp6array($ret['ip_address']['ip']); $q = $this->dbdat->query("select name,name_code,homepage FROM udger_datacenter_range6 From c9b08033dd99bec0b989f92f7c93e3390711d3c3 Mon Sep 17 00:00:00 2001 From: "udger.com" Date: Fri, 9 Sep 2016 16:10:51 +0200 Subject: [PATCH 06/13] open DB READONLY --- src/Parser.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Parser.php b/src/Parser.php index 5698754..a1816a4 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -537,7 +537,7 @@ protected function setDBdat() { if (is_null($this->dbdat)) { $this->logger->debug(sprintf("db: open file: %s", $this->path)); - $this->dbdat = new \SQLite3($this->path); + $this->dbdat = new \SQLite3($this->path, SQLITE3_OPEN_READONLY); } } @@ -551,12 +551,8 @@ public function setDataFile($path) { if (false === file_exists($path)) { throw new \Exception(sprintf("%s does not exist", $path)); - } - - if (false === is_writable($path)) { - throw new \Exception(sprintf("%s is not writable", $path)); - } - + } + $this->path = $path; return true; From 2aca203f193b4913719655f4d3c11273fd4e5772 Mon Sep 17 00:00:00 2001 From: "udger.com" Date: Fri, 9 Sep 2016 18:42:33 +0200 Subject: [PATCH 07/13] add LRU cache --- src/Parser.php | 456 ++++++++++++++++++++++++++++++------------------- 1 file changed, 277 insertions(+), 179 deletions(-) diff --git a/src/Parser.php b/src/Parser.php index a1816a4..69b850e 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -74,6 +74,21 @@ class Parser implements ParserInterface * @var IPInterface */ protected $ipHelper; + + /** + * @boolean LRU cache enable/disable + */ + protected $cacheEnable = true; + + /** + * @array LRU cache + */ + protected $cache = array(); + + /** + * @int LRU cache size + */ + protected $cacheSize = 3000; /** * @param LoggerInterface $logger @@ -244,190 +259,203 @@ public function parse() if (!empty($this->ua)) { $this->logger->debug("parse useragent string: START (useragent: " . $this->ua . ")"); - $client_id = 0; - $client_class_id = -1; - $os_id = 0; - $deviceclass_id = 0; - $ret['user_agent']['ua_string'] = $this->ua; - $ret['user_agent']['ua_class'] = 'Unrecognized'; - $ret['user_agent']['ua_class_code'] = 'unrecognized'; - - // crawler - $q = $this->dbdat->query("SELECT udger_crawler_list.id as botid,name,ver,ver_major,last_seen,respect_robotstxt,family,family_code,family_homepage,family_icon,vendor,vendor_code,vendor_homepage,crawler_classification,crawler_classification_code - FROM udger_crawler_list - LEFT JOIN udger_crawler_class ON udger_crawler_class.id=udger_crawler_list.class_id - WHERE ua_string='" . $this->dbdat->escapeString($this->ua) . "'"); - - if ($r = $q->fetchArray(SQLITE3_ASSOC)) { - $this->logger->debug("parse useragent string: crawler found"); - - $client_class_id = 99; - $ret['user_agent']['ua_class'] = 'Crawler'; - $ret['user_agent']['ua_class_code'] = 'crawler'; - $ret['user_agent']['ua'] = $r['name']; - $ret['user_agent']['ua_version'] = $r['ver']; - $ret['user_agent']['ua_version_major'] = $r['ver_major']; - $ret['user_agent']['ua_family'] = $r['family']; - $ret['user_agent']['ua_family_code'] = $r['family_code']; - $ret['user_agent']['ua_family_homepage'] = $r['family_homepage']; - $ret['user_agent']['ua_family_vendor'] = $r['vendor']; - $ret['user_agent']['ua_family_vendor_code'] = $r['vendor_code']; - $ret['user_agent']['ua_family_vendor_homepage'] = $r['vendor_homepage']; - $ret['user_agent']['ua_family_icon'] = $r['family_icon']; - $ret['user_agent']['ua_family_info_url'] = "https://udger.com/resources/ua-list/bot-detail?bot=" . $r['family'] . "#id" . $r['botid']; - $ret['user_agent']['crawler_last_seen'] = $r['last_seen']; - $ret['user_agent']['crawler_category'] = $r['crawler_classification']; - $ret['user_agent']['crawler_category_code'] = $r['crawler_classification_code']; - $ret['user_agent']['crawler_respect_robotstxt'] = $r['respect_robotstxt']; - } else { - // client - $q = $this->dbdat->query("SELECT class_id,client_id,regstring,name,name_code,homepage,icon,icon_big,engine,vendor,vendor_code,vendor_homepage,uptodate_current_version,client_classification,client_classification_code - FROM udger_client_regex - JOIN udger_client_list ON udger_client_list.id=udger_client_regex.client_id - JOIN udger_client_class ON udger_client_class.id=udger_client_list.class_id - ORDER BY sequence ASC"); - while ($r = $q->fetchArray(SQLITE3_ASSOC)) { - if (@preg_match($r["regstring"], $this->ua, $result)) { - $this->logger->debug("parse useragent string: client found"); - $client_id = $r['client_id']; - $client_class_id = $r['class_id']; - $ret['user_agent']['ua_class'] = $r['client_classification']; - $ret['user_agent']['ua_class_code'] = $r['client_classification_code']; - if (isset($result[1])) { - $ret['user_agent']['ua'] = $r['name'] . " " . $result[1]; - $ret['user_agent']['ua_version'] = $result[1]; - $ver_major = explode(".", $result[1]); - $ret['user_agent']['ua_version_major'] = $ver_major[0]; - } else { - $ret['user_agent']['ua'] = $r['name']; - $ret['user_agent']['ua_version'] = ''; - $ret['user_agent']['ua_version_major'] = ''; + + $usedCache = false; + if($this->cacheEnable) { + $retCache = $this->getCache( md5($this->ua) ); + if($retCache) { + $ret['user_agent'] = unserialize($retCache); + $usedCache = true; + } + } + if(!$usedCache) { + $client_id = 0; + $client_class_id = -1; + $os_id = 0; + $deviceclass_id = 0; + $ret['user_agent']['ua_string'] = $this->ua; + $ret['user_agent']['ua_class'] = 'Unrecognized'; + $ret['user_agent']['ua_class_code'] = 'unrecognized'; + + // crawler + $q = $this->dbdat->query("SELECT udger_crawler_list.id as botid,name,ver,ver_major,last_seen,respect_robotstxt,family,family_code,family_homepage,family_icon,vendor,vendor_code,vendor_homepage,crawler_classification,crawler_classification_code + FROM udger_crawler_list + LEFT JOIN udger_crawler_class ON udger_crawler_class.id=udger_crawler_list.class_id + WHERE ua_string='" . $this->dbdat->escapeString($this->ua) . "'"); + + if ($r = $q->fetchArray(SQLITE3_ASSOC)) { + $this->logger->debug("parse useragent string: crawler found"); + + $client_class_id = 99; + $ret['user_agent']['ua_class'] = 'Crawler'; + $ret['user_agent']['ua_class_code'] = 'crawler'; + $ret['user_agent']['ua'] = $r['name']; + $ret['user_agent']['ua_version'] = $r['ver']; + $ret['user_agent']['ua_version_major'] = $r['ver_major']; + $ret['user_agent']['ua_family'] = $r['family']; + $ret['user_agent']['ua_family_code'] = $r['family_code']; + $ret['user_agent']['ua_family_homepage'] = $r['family_homepage']; + $ret['user_agent']['ua_family_vendor'] = $r['vendor']; + $ret['user_agent']['ua_family_vendor_code'] = $r['vendor_code']; + $ret['user_agent']['ua_family_vendor_homepage'] = $r['vendor_homepage']; + $ret['user_agent']['ua_family_icon'] = $r['family_icon']; + $ret['user_agent']['ua_family_info_url'] = "https://udger.com/resources/ua-list/bot-detail?bot=" . $r['family'] . "#id" . $r['botid']; + $ret['user_agent']['crawler_last_seen'] = $r['last_seen']; + $ret['user_agent']['crawler_category'] = $r['crawler_classification']; + $ret['user_agent']['crawler_category_code'] = $r['crawler_classification_code']; + $ret['user_agent']['crawler_respect_robotstxt'] = $r['respect_robotstxt']; + } else { + // client + $q = $this->dbdat->query("SELECT class_id,client_id,regstring,name,name_code,homepage,icon,icon_big,engine,vendor,vendor_code,vendor_homepage,uptodate_current_version,client_classification,client_classification_code + FROM udger_client_regex + JOIN udger_client_list ON udger_client_list.id=udger_client_regex.client_id + JOIN udger_client_class ON udger_client_class.id=udger_client_list.class_id + ORDER BY sequence ASC"); + while ($r = $q->fetchArray(SQLITE3_ASSOC)) { + if (@preg_match($r["regstring"], $this->ua, $result)) { + $this->logger->debug("parse useragent string: client found"); + $client_id = $r['client_id']; + $client_class_id = $r['class_id']; + $ret['user_agent']['ua_class'] = $r['client_classification']; + $ret['user_agent']['ua_class_code'] = $r['client_classification_code']; + if (isset($result[1])) { + $ret['user_agent']['ua'] = $r['name'] . " " . $result[1]; + $ret['user_agent']['ua_version'] = $result[1]; + $ver_major = explode(".", $result[1]); + $ret['user_agent']['ua_version_major'] = $ver_major[0]; + } else { + $ret['user_agent']['ua'] = $r['name']; + $ret['user_agent']['ua_version'] = ''; + $ret['user_agent']['ua_version_major'] = ''; + } + $ret['user_agent']['ua_uptodate_current_version'] = $r['uptodate_current_version']; + $ret['user_agent']['ua_family'] = $r['name']; + $ret['user_agent']['ua_family_code'] = $r['name_code']; + $ret['user_agent']['ua_family_homepage'] = $r['homepage']; + $ret['user_agent']['ua_family_vendor'] = $r['vendor']; + $ret['user_agent']['ua_family_vendor_code'] = $r['vendor_code']; + $ret['user_agent']['ua_family_vendor_homepage'] = $r['vendor_homepage']; + $ret['user_agent']['ua_family_icon'] = $r['icon']; + $ret['user_agent']['ua_family_icon_big'] = $r['icon_big']; + $ret['user_agent']['ua_family_info_url'] = "https://udger.com/resources/ua-list/browser-detail?browser=" . $r['name']; + $ret['user_agent']['ua_engine'] = $r['engine']; + break; } - $ret['user_agent']['ua_uptodate_current_version'] = $r['uptodate_current_version']; - $ret['user_agent']['ua_family'] = $r['name']; - $ret['user_agent']['ua_family_code'] = $r['name_code']; - $ret['user_agent']['ua_family_homepage'] = $r['homepage']; - $ret['user_agent']['ua_family_vendor'] = $r['vendor']; - $ret['user_agent']['ua_family_vendor_code'] = $r['vendor_code']; - $ret['user_agent']['ua_family_vendor_homepage'] = $r['vendor_homepage']; - $ret['user_agent']['ua_family_icon'] = $r['icon']; - $ret['user_agent']['ua_family_icon_big'] = $r['icon_big']; - $ret['user_agent']['ua_family_info_url'] = "https://udger.com/resources/ua-list/browser-detail?browser=" . $r['name']; - $ret['user_agent']['ua_engine'] = $r['engine']; - break; } - } - // os - $q = $this->dbdat->query("SELECT os_id,regstring,family,family_code,name,name_code,homepage,icon,icon_big,vendor,vendor_code,vendor_homepage - FROM udger_os_regex - JOIN udger_os_list ON udger_os_list.id=udger_os_regex.os_id - ORDER BY sequence ASC"); - while ($r = $q->fetchArray(SQLITE3_ASSOC)) { - if (@preg_match($r["regstring"], $this->ua, $result)) { - $this->logger->debug("parse useragent string: os found"); - $os_id = $r['os_id']; - $ret['user_agent']['os'] = $r['name']; - $ret['user_agent']['os_code'] = $r['name_code']; - $ret['user_agent']['os_homepage'] = $r['homepage']; - $ret['user_agent']['os_icon'] = $r['icon']; - $ret['user_agent']['os_icon_big'] = $r['icon_big']; - $ret['user_agent']['os_info_url'] = "https://udger.com/resources/ua-list/os-detail?os=" . $r['name']; - $ret['user_agent']['os_family'] = $r['family']; - $ret['user_agent']['os_family_code'] = $r['family_code']; - $ret['user_agent']['os_family_vendor'] = $r['vendor']; - $ret['user_agent']['os_family_vendor_code'] = $r['vendor_code']; - $ret['user_agent']['os_family_vendor_homepage'] = $r['vendor_homepage']; - break; + // os + $q = $this->dbdat->query("SELECT os_id,regstring,family,family_code,name,name_code,homepage,icon,icon_big,vendor,vendor_code,vendor_homepage + FROM udger_os_regex + JOIN udger_os_list ON udger_os_list.id=udger_os_regex.os_id + ORDER BY sequence ASC"); + while ($r = $q->fetchArray(SQLITE3_ASSOC)) { + if (@preg_match($r["regstring"], $this->ua, $result)) { + $this->logger->debug("parse useragent string: os found"); + $os_id = $r['os_id']; + $ret['user_agent']['os'] = $r['name']; + $ret['user_agent']['os_code'] = $r['name_code']; + $ret['user_agent']['os_homepage'] = $r['homepage']; + $ret['user_agent']['os_icon'] = $r['icon']; + $ret['user_agent']['os_icon_big'] = $r['icon_big']; + $ret['user_agent']['os_info_url'] = "https://udger.com/resources/ua-list/os-detail?os=" . $r['name']; + $ret['user_agent']['os_family'] = $r['family']; + $ret['user_agent']['os_family_code'] = $r['family_code']; + $ret['user_agent']['os_family_vendor'] = $r['vendor']; + $ret['user_agent']['os_family_vendor_code'] = $r['vendor_code']; + $ret['user_agent']['os_family_vendor_homepage'] = $r['vendor_homepage']; + break; + } } - } - // client_os_relation - if ($os_id == 0 AND $client_id != 0) { - $q = $this->dbdat->query("SELECT os_id,family,family_code,name,name_code,homepage,icon,icon_big,vendor,vendor_code,vendor_homepage - FROM udger_client_os_relation - JOIN udger_os_list ON udger_os_list.id=udger_client_os_relation.os_id - WHERE client_id=" . $client_id . " "); - if ($r = $q->fetchArray(SQLITE3_ASSOC)) { - $this->logger->debug("parse useragent string: client os relation found"); - $os_id = $r['os_id']; - $ret['user_agent']['os'] = $r['name']; - $ret['user_agent']['os_code'] = $r['name_code']; - $ret['user_agent']['os_homepage'] = $r['homepage']; - $ret['user_agent']['os_icon'] = $r['icon']; - $ret['user_agent']['os_icon_big'] = $r['icon_big']; - $ret['user_agent']['os_info_url'] = "https://udger.com/resources/ua-list/os-detail?os=" . $r['name']; - $ret['user_agent']['os_family'] = $r['family']; - $ret['user_agent']['os_family_code'] = $r['family_code']; - $ret['user_agent']['os_family_vendor'] = $r['vendor']; - $ret['user_agent']['os_family_vendor_code'] = $r['vendor_code']; - $ret['user_agent']['os_family_vendor_homepage'] = $r['vendor_homepage']; + // client_os_relation + if ($os_id == 0 AND $client_id != 0) { + $q = $this->dbdat->query("SELECT os_id,family,family_code,name,name_code,homepage,icon,icon_big,vendor,vendor_code,vendor_homepage + FROM udger_client_os_relation + JOIN udger_os_list ON udger_os_list.id=udger_client_os_relation.os_id + WHERE client_id=" . $client_id . " "); + if ($r = $q->fetchArray(SQLITE3_ASSOC)) { + $this->logger->debug("parse useragent string: client os relation found"); + $os_id = $r['os_id']; + $ret['user_agent']['os'] = $r['name']; + $ret['user_agent']['os_code'] = $r['name_code']; + $ret['user_agent']['os_homepage'] = $r['homepage']; + $ret['user_agent']['os_icon'] = $r['icon']; + $ret['user_agent']['os_icon_big'] = $r['icon_big']; + $ret['user_agent']['os_info_url'] = "https://udger.com/resources/ua-list/os-detail?os=" . $r['name']; + $ret['user_agent']['os_family'] = $r['family']; + $ret['user_agent']['os_family_code'] = $r['family_code']; + $ret['user_agent']['os_family_vendor'] = $r['vendor']; + $ret['user_agent']['os_family_vendor_code'] = $r['vendor_code']; + $ret['user_agent']['os_family_vendor_homepage'] = $r['vendor_homepage']; + } } - } - //device - $q = $this->dbdat->query("SELECT deviceclass_id,regstring,name,name_code,icon,icon_big - FROM udger_deviceclass_regex - JOIN udger_deviceclass_list ON udger_deviceclass_list.id=udger_deviceclass_regex.deviceclass_id - ORDER BY sequence ASC"); - - while ($r = $q->fetchArray(SQLITE3_ASSOC)) { - if (@preg_match($r["regstring"], $this->ua, $result)) { - $this->logger->debug("parse useragent string: device found by regex"); - $deviceclass_id = $r['deviceclass_id']; - $ret['user_agent']['device_class'] = $r['name']; - $ret['user_agent']['device_class_code'] = $r['name_code']; - $ret['user_agent']['device_class_icon'] = $r['icon']; - $ret['user_agent']['device_class_icon_big'] = $r['icon_big']; - $ret['user_agent']['device_class_info_url'] = "https://udger.com/resources/ua-list/device-detail?device=" . $r['name']; - break; + //device + $q = $this->dbdat->query("SELECT deviceclass_id,regstring,name,name_code,icon,icon_big + FROM udger_deviceclass_regex + JOIN udger_deviceclass_list ON udger_deviceclass_list.id=udger_deviceclass_regex.deviceclass_id + ORDER BY sequence ASC"); + + while ($r = $q->fetchArray(SQLITE3_ASSOC)) { + if (@preg_match($r["regstring"], $this->ua, $result)) { + $this->logger->debug("parse useragent string: device found by regex"); + $deviceclass_id = $r['deviceclass_id']; + $ret['user_agent']['device_class'] = $r['name']; + $ret['user_agent']['device_class_code'] = $r['name_code']; + $ret['user_agent']['device_class_icon'] = $r['icon']; + $ret['user_agent']['device_class_icon_big'] = $r['icon_big']; + $ret['user_agent']['device_class_info_url'] = "https://udger.com/resources/ua-list/device-detail?device=" . $r['name']; + break; + } } - } - if ($deviceclass_id == 0 AND $client_class_id != -1) { - $q = $this->dbdat->query("SELECT deviceclass_id,name,name_code,icon,icon_big - FROM udger_deviceclass_list - JOIN udger_client_class ON udger_client_class.deviceclass_id=udger_deviceclass_list.id - WHERE udger_client_class.id=" . $client_class_id . " "); - if ($r = $q->fetchArray(SQLITE3_ASSOC)) { - $this->logger->debug("parse useragent string: device found by deviceclass"); - $deviceclass_id = $r['deviceclass_id']; - $ret['user_agent']['device_class'] = $r['name']; - $ret['user_agent']['device_class_code'] = $r['name_code']; - $ret['user_agent']['device_class_icon'] = $r['icon']; - $ret['user_agent']['device_class_icon_big'] = $r['icon_big']; - $ret['user_agent']['device_class_info_url'] = "https://udger.com/resources/ua-list/device-detail?device=" . $r['name']; + if ($deviceclass_id == 0 AND $client_class_id != -1) { + $q = $this->dbdat->query("SELECT deviceclass_id,name,name_code,icon,icon_big + FROM udger_deviceclass_list + JOIN udger_client_class ON udger_client_class.deviceclass_id=udger_deviceclass_list.id + WHERE udger_client_class.id=" . $client_class_id . " "); + if ($r = $q->fetchArray(SQLITE3_ASSOC)) { + $this->logger->debug("parse useragent string: device found by deviceclass"); + $deviceclass_id = $r['deviceclass_id']; + $ret['user_agent']['device_class'] = $r['name']; + $ret['user_agent']['device_class_code'] = $r['name_code']; + $ret['user_agent']['device_class_icon'] = $r['icon']; + $ret['user_agent']['device_class_icon_big'] = $r['icon_big']; + $ret['user_agent']['device_class_info_url'] = "https://udger.com/resources/ua-list/device-detail?device=" . $r['name']; + } } - } - - // device marketname - if($ret['user_agent']['os_family_code']) { - $q = $this->dbdat->query("SELECT id,regstring FROM udger_devicename_regex WHERE - ((os_family_code='".$ret['user_agent']['os_family_code']."' AND os_code='-all-') - OR - (os_family_code='".$ret['user_agent']['os_family_code']."' AND os_code='".$ret['user_agent']['os_code']."')) - order by sequence"); - while ($r = $q->fetchArray(SQLITE3_ASSOC)) { - @preg_match($r["regstring"],$this->ua,$result); - - if($result[1]) { - $qC=$this->dbdat->query("SELECT marketname,brand_code,brand,brand_url,icon,icon_big - FROM udger_devicename_list - JOIN udger_devicename_brand ON udger_devicename_brand.id=udger_devicename_list.brand_id - WHERE regex_id=".$r["id"]." and code = '".trim($result[1])."' "); - - if($rC = $qC->fetchArray(SQLITE3_ASSOC)) { - $this->logger->debug("parse useragent string: device marketname found"); - $ret['user_agent']['device_marketname'] = $rC['marketname']; - $ret['user_agent']['device_brand'] = $rC['brand']; - $ret['user_agent']['device_brand_code'] = $rC['brand_code']; - $ret['user_agent']['device_brand_homepage'] = $rC['brand_url']; - $ret['user_agent']['device_brand_icon'] = $rC['icon']; - $ret['user_agent']['device_brand_icon_big'] = $rC['icon_big']; - $ret['user_agent']['device_brand_info_url'] = "https://udger.com/resources/ua-list/devices-brand-detail?brand=".$rC['brand_code']; - - break; - } + + // device marketname + if($ret['user_agent']['os_family_code']) { + $q = $this->dbdat->query("SELECT id,regstring FROM udger_devicename_regex WHERE + ((os_family_code='".$ret['user_agent']['os_family_code']."' AND os_code='-all-') + OR + (os_family_code='".$ret['user_agent']['os_family_code']."' AND os_code='".$ret['user_agent']['os_code']."')) + order by sequence"); + while ($r = $q->fetchArray(SQLITE3_ASSOC)) { + @preg_match($r["regstring"],$this->ua,$result); + + if($result[1]) { + $qC=$this->dbdat->query("SELECT marketname,brand_code,brand,brand_url,icon,icon_big + FROM udger_devicename_list + JOIN udger_devicename_brand ON udger_devicename_brand.id=udger_devicename_list.brand_id + WHERE regex_id=".$r["id"]." and code = '".trim($result[1])."' "); + + if($rC = $qC->fetchArray(SQLITE3_ASSOC)) { + $this->logger->debug("parse useragent string: device marketname found"); + $ret['user_agent']['device_marketname'] = $rC['marketname']; + $ret['user_agent']['device_brand'] = $rC['brand']; + $ret['user_agent']['device_brand_code'] = $rC['brand_code']; + $ret['user_agent']['device_brand_homepage'] = $rC['brand_url']; + $ret['user_agent']['device_brand_icon'] = $rC['icon']; + $ret['user_agent']['device_brand_icon_big'] = $rC['icon_big']; + $ret['user_agent']['device_brand_info_url'] = "https://udger.com/resources/ua-list/devices-brand-detail?brand=".$rC['brand_code']; + + break; + } + } } } + if($this->cacheEnable) { + $this->setCache( md5($this->ua) , serialize($ret['user_agent']) ); + } } - } $this->logger->debug("parse useragent string: END, unset useragent string"); @@ -537,10 +565,76 @@ protected function setDBdat() { if (is_null($this->dbdat)) { $this->logger->debug(sprintf("db: open file: %s", $this->path)); - $this->dbdat = new \SQLite3($this->path, SQLITE3_OPEN_READONLY); + $this->dbdat = new \SQLite3($this->path); } } - + + /** + * LRU cashe set + */ + protected function setCache($key, $value) { + $this->logger->debug('LRUcache: set to key' . $key); + $this->cache[$key] = $value; + if (count($this->cache) > $this->cacheSize) { + array_shift($this->cache); + } + } + + /** + * LRU cashe get + */ + protected function getCache($key) { + $this->logger->debug('LRUcache: get key' . $key); + if ( ! isset($this->cache[$key])) { + $this->logger->debug('LRUcache: key' . $key . ' Not Found' ); + return null; + } + // Put the value gotten to last. + $tmpValue = $this->cache[$key]; + unset($this->cache[$key]); + $this->cache[$key] = $tmpValue; + $this->logger->debug('LRUcache: key' . $key . ' Found' ); + return $tmpValue; + } + + /** + * Set LRU cache enable/disable + * + * @param bool + * @return bool + */ + public function setCacheEnable($set) + { + $this->cacheEnable = $set; + $log = $set ? 'true' : 'false'; + $this->logger->debug('LRUcache: enable/disable: ' . $log ); + return true; + } + + /** + * Set LRU cache enable/disable + * + * @param Int + * @return bool + */ + public function setCacheSize($size) + { + $this->cacheSize = $size; + $this->logger->debug('LRUcache: set size: ' . $size ); + return true; + } + /** + * Clear LRU cache + * + * @return bool + */ + public function clearCache() + { + $this->cache = array(); + $this->logger->debug('LRUcache: clear cache'); + return true; + } + /** * Set path to sqlite file * @@ -551,8 +645,12 @@ public function setDataFile($path) { if (false === file_exists($path)) { throw new \Exception(sprintf("%s does not exist", $path)); - } - + } + + if (false === is_writable($path)) { + throw new \Exception(sprintf("%s is not writable", $path)); + } + $this->path = $path; return true; From 4316b2348393225a26423d103cf758d9bde6228e Mon Sep 17 00:00:00 2001 From: "udger.com" Date: Fri, 9 Sep 2016 18:50:54 +0200 Subject: [PATCH 08/13] SQLITE3_OPEN_READONLY --- src/Parser.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Parser.php b/src/Parser.php index 69b850e..dc0b0fb 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -565,7 +565,7 @@ protected function setDBdat() { if (is_null($this->dbdat)) { $this->logger->debug(sprintf("db: open file: %s", $this->path)); - $this->dbdat = new \SQLite3($this->path); + $this->dbdat = new \SQLite3($this->path, SQLITE3_OPEN_READONLY); } } @@ -645,11 +645,7 @@ public function setDataFile($path) { if (false === file_exists($path)) { throw new \Exception(sprintf("%s does not exist", $path)); - } - - if (false === is_writable($path)) { - throw new \Exception(sprintf("%s is not writable", $path)); - } + } $this->path = $path; From 5a84d07e230f54789b519c9100a0c1c9438c7005 Mon Sep 17 00:00:00 2001 From: "udger.com" Date: Sat, 10 Sep 2016 14:20:57 +0200 Subject: [PATCH 09/13] add device marketname and set LRU cache --- README.md | 73 +++++++++++++++++++++++++--------------------- examples/parse.php | 2 ++ 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index b4d64cc..9d6be7b 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ require_once dirname(__DIR__) . '/vendor/autoload.php'; $factory = new Udger\ParserFactory(); $parser = $factory->getParser(); $parser->setDataFile(sys_get_temp_dir() . "/udgercache/udgerdb_v3.dat"); -$parser->setUA('Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.97 Safari/537.36'); +$parser->setUA('Mozilla/5.0 (Linux; Android 5.1.1; SAMSUNG SM-A510F Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/3.5 Chrome/38.0.2125.102 Mobile Safari/537.36'); $parser->setIP("2A02:598:7000:116:0:0:0:101"); $ret = $parser->parse(); echo "
";
@@ -38,41 +38,46 @@ echo "
"; Array ( - [user_agent] => Array + [user_agent] => Array ( - [ua_string] => Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.97 Safari/537.36 - [ua_class] => Browser - [ua_class_code] => browser - [ua] => Chrome 48.0.2564.97 - [ua_version] => 48.0.2564.97 - [ua_version_major] => 48 - [ua_uptodate_current_version] => 48 - [ua_family] => Chrome - [ua_family_code] => chrome - [ua_family_homepage] => http://www.google.com/chrome/ - [ua_family_vendor] => Google Inc. - [ua_family_vendor_code] => google_inc - [ua_family_vendor_homepage] => https://www.google.com/about/company/ - [ua_family_icon] => chrome.png - [ua_family_icon_big] => chrome_big.png - [ua_family_info_url] => https://udger.com/resources/ua-list/browser-detail?browser=Chrome + [ua_string] => Mozilla/5.0 (Linux; Android 5.1.1; SAMSUNG SM-A510F Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/3.5 Chrome/38.0.2125.102 Mobile Safari/537.36 + [ua_class] => Mobile browser + [ua_class_code] => mobile_browser + [ua] => Mobile Samsung Browser 3.5 + [ua_version] => 3.5 + [ua_version_major] => 3 + [ua_uptodate_current_version] => + [ua_family] => Mobile Samsung Browser + [ua_family_code] => mobile_samsung_browser + [ua_family_homepage] => http://developer.samsung.com/internet + [ua_family_vendor] => SAMSUNG + [ua_family_vendor_code] => samsung + [ua_family_vendor_homepage] => http://www.samsung.com/ + [ua_family_icon] => samsung_browser.png + [ua_family_icon_big] => samsung_browser_big.png + [ua_family_info_url] => https://udger.com/resources/ua-list/browser-detail?browser=Mobile Samsung Browser [ua_engine] => WebKit/Blink - [os] => Windows 7 - [os_code] => windows_7 - [os_homepage] => https://en.wikipedia.org/wiki/Windows_7 - [os_icon] => windows-7.png - [os_icon_big] => windows-7_big.png - [os_info_url] => https://udger.com/resources/ua-list/os-detail?os=Windows 7 - [os_family] => Windows - [os_family_code] => windows - [os_family_vendor] => Microsoft Corporation. - [os_family_vendor_code] => microsoft_corporation - [os_family_vendor_homepage] => https://www.microsoft.com/about/ - [device_class] => Desktop - [device_class_code] => desktop - [device_class_icon] => desktop.png - [device_class_icon_big] => desktop_big.png - [device_class_info_url] => https://udger.com/resources/ua-list/device-detail?device=Desktop + [os] => Android 5.1 lollipop + [os_code] => android_5_1 + [os_homepage] => https://en.wikipedia.org/wiki/Android_Lollipop + [os_icon] => android.png + [os_icon_big] => android_big.png + [os_info_url] => https://udger.com/resources/ua-list/os-detail?os=Android 5.1 lollipop + [os_family] => Android + [os_family_code] => android + [os_family_vendor] => Google, Inc. + [os_family_vendor_code] => google_inc + [os_family_vendor_homepage] => https://www.google.com/about/company/ + [device_class] => Smartphone + [device_class_code] => smartphone + [device_class_icon] => phone.png + [device_class_icon_big] => phone_big.png + [device_class_info_url] => https://udger.com/resources/ua-list/device-detail?device=Smartphone + [device_marketname] => Galaxy A5 (2016) + [device_vendor] => Samsung + [device_vendor_code] => samsung + [device_vendor_homepage] => http://www.samsung.com/ + [device_vendor_icon] => samsung.png [crawler_last_seen] => [crawler_category] => [crawler_category_code] => diff --git a/examples/parse.php b/examples/parse.php index f7c2b40..10ade5a 100644 --- a/examples/parse.php +++ b/examples/parse.php @@ -5,6 +5,8 @@ // creates a new UdgerParser object $factory = new Udger\ParserFactory(sys_get_temp_dir() . "/udgercache/udgerdb_v3.dat"); $parser = $factory->getParser(); +//$parser->setCacheEnable(false); +//$parser->setCacheSize(4000); try { $parser->setUA('Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.97 Safari/537.36'); From e0e905d43691d2b6703da5abc9cabe50f6481842 Mon Sep 17 00:00:00 2001 From: "udger.com" Date: Sat, 10 Sep 2016 18:13:44 +0200 Subject: [PATCH 10/13] add doc link --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9d6be7b..8a0659c 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,9 @@ Array ### Automatic updates download - for autoupdate data use Udger data updater (https://udger.com/support/documentation/?doc=62) +### Documentation for programmers +- https://udger.com/pub/documentation/parser/PHP/html/ + ### Author - The Udger.com Team (info@udger.com) From 6f42e675a7a160f8ed164a3970f39995306b6efe Mon Sep 17 00:00:00 2001 From: "udger.com" Date: Wed, 28 Sep 2016 09:31:25 +0200 Subject: [PATCH 11/13] fix getIpVersion, getIpLong --- src/Helper/IP.php | 2 +- src/Parser.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Helper/IP.php b/src/Helper/IP.php index e199e96..6c0b2e8 100644 --- a/src/Helper/IP.php +++ b/src/Helper/IP.php @@ -22,7 +22,7 @@ public function getIpVersion($ip) return self::IPv6; } - if (false !== filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + else if (false !== filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { return self::IPv4; } // invalid ip diff --git a/src/Parser.php b/src/Parser.php index dc0b0fb..c22a46d 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -513,9 +513,9 @@ public function parse() $ret['ip_address']['ip_classification_code'] = 'unrecognized'; } - if ($this->ipHelper->getIpVersion($ret['ip_address']['ip_ver']) === IPInterface::IPv4) { + if ($this->ipHelper->getIpVersion($ret['ip_address']['ip']) === IPInterface::IPv4) { - $ipLong = $this->ipHelper->getIpLongsprintf($ret['ip_address']['ip']); + $ipLong = $this->ipHelper->getIpLong($ret['ip_address']['ip']); $q = $this->dbdat->query("select name,name_code,homepage FROM udger_datacenter_range @@ -528,7 +528,7 @@ public function parse() $ret['ip_address']['datacenter_homepage'] = $r['homepage']; } } - else if ($this->ipHelper->getIpVersion($ret['ip_address']['ip_ver']) === IPInterface::IPv6) { + else if ($this->ipHelper->getIpVersion($ret['ip_address']['ip']) === IPInterface::IPv6) { $ipInt = $this->ipHelper->getIp6array($ret['ip_address']['ip']); $q = $this->dbdat->query("select name,name_code,homepage FROM udger_datacenter_range6 From 1814d83b2a6283ed6326557acb515dc79b817e6b Mon Sep 17 00:00:00 2001 From: Shawn Bayer Date: Mon, 3 Oct 2016 18:14:03 -0400 Subject: [PATCH 12/13] fix offset 1 --- src/Parser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Parser.php b/src/Parser.php index c22a46d..44049c5 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -431,7 +431,7 @@ public function parse() while ($r = $q->fetchArray(SQLITE3_ASSOC)) { @preg_match($r["regstring"],$this->ua,$result); - if($result[1]) { + if(array_key_exists(1, $result)) { $qC=$this->dbdat->query("SELECT marketname,brand_code,brand,brand_url,icon,icon_big FROM udger_devicename_list JOIN udger_devicename_brand ON udger_devicename_brand.id=udger_devicename_list.brand_id From 835e2eaf61ce94f2fecc746f3359e45caea79f10 Mon Sep 17 00:00:00 2001 From: Jaroslav Mallat Date: Wed, 4 Jan 2017 12:20:07 +0100 Subject: [PATCH 13/13] small edit --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a0659c..7d6db73 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ It also provides information about IP addresses (Public proxies, VPN services, T ### Features - Fast +- LRU cache - Released under the GNU (LGPL v.3) ### Install @@ -27,7 +28,9 @@ Here's a quick example: require_once dirname(__DIR__) . '/vendor/autoload.php'; $factory = new Udger\ParserFactory(); $parser = $factory->getParser(); -$parser->setDataFile(sys_get_temp_dir() . "/udgercache/udgerdb_v3.dat"); +$parser->setDataFile(sys_get_temp_dir() . "/udgercache/udgerdb_v3.dat"); +//$parser->setCacheEnable(false); +//$parser->setCacheSize(4000); $parser->setUA('Mozilla/5.0 (Linux; Android 5.1.1; SAMSUNG SM-A510F Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/3.5 Chrome/38.0.2125.102 Mobile Safari/537.36'); $parser->setIP("2A02:598:7000:116:0:0:0:101"); $ret = $parser->parse();