Skip to content

Commit ead674c

Browse files
committed
Version 2.6 (release)
1 parent 841e567 commit ead674c

9 files changed

+215
-41
lines changed

.editorconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
root = true
22

3-
[*.{php,js,html,css}]
3+
[*.{php}]
44
charset = utf-8
55
indent_style = tab
66
indent_size = 4

CHANGELOG.md

+15
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,21 @@
22

33
All notable changes to this `PHP Browser Detection` project documented in this file.
44

5+
## [2.6] - 2023-03-12
6+
7+
### Added
8+
9+
- About ~ 10 browsers/apps detection added;
10+
- Added detection of rare Windows OS User-Agents.
11+
12+
### Changed
13+
14+
- iOS WebKit WebView detection improved.
15+
16+
### Fixed
17+
18+
- EdgeHTML browser engine (Edge Browser from 12 to 18 versions) no longer detects as Chromium engine based
19+
520
## [2.5] - 2023-03-10
621

722
### Added

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
A PHP library to detect browser, OS, platform and device type by User-Agent parsing.\
44
This library focused on high performance and low memory usage HTTP client parsing.\
5-
Uses a simple and fast algorithm to accurately detect about ~ 200 browsers/apps and over 60 OS.\
5+
Uses a simple and fast algorithm to accurately detect more than 200 browsers/apps and over 60 OS.\
66
For most commonly browsers parsing process took less than 0.0005 second even on low-level shared hosting.\
77
In the case of rare User-Agents recognized time is less than 0.0008 second for the same conditioned hosting environment.\
88
The library supports only really actual Browsers and OS without support for outdated environments that are actually not used now.\

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "foroco/php-browser-detection",
33
"type": "library",
4-
"description": "Ultra fast PHP library to detect browser, OS, platform and device type by User-Agent parsing.",
4+
"description": "Ultra fast PHP library to detect browser, OS, platform and device type by User-Agent parsing",
55
"keywords": ["user-agent","php","browser","detection","environment","useragent"],
66
"homepage": "https://github.com/foroco/php-browser-detection",
77
"license": "MIT",

src/BrowserDetection.php

+57-30
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2626
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2727
*
28-
* @version 2.5
29-
* @last-modified March 10, 2023
28+
* @version 2.6
29+
* @last-modified March 12, 2023
3030
* @link https://github.com/foroco/php-browser-detection
3131
*/
3232

@@ -343,12 +343,18 @@ private function getResult()
343343
if (empty($this->result_os_version))
344344
{
345345
if ($this->match_ua('/Win16/')) $this->result_os_version = '3.1';
346-
if ($this->match_ua('/(Windows 95)|(Win95)|(Windows_95)/')) $this->result_os_version = '95';
347-
if ($this->match_ua('/(Windows 98)|(Win98)/')) $this->result_os_version = '98';
348-
if ($this->match_ua('/(Windows 2000)/')) $this->result_os_version = '2000';
349-
if ($this->match_ua('/(Win NT 5\.0)/')) $this->result_os_version = '2000';
350-
if ($this->match_ua('/(Windows XP)/')) $this->result_os_version = 'XP';
346+
if ($this->match_ua('/(Windows\s95|Win95|Windows_95)/')) $this->result_os_version = '95';
347+
if ($this->match_ua('/(Windows\s98|Win98)/')) $this->result_os_version = '98';
348+
if ($this->match_ua('/Windows\s2000/')) $this->result_os_version = '2000';
349+
if ($this->match_ua('/Win\sNT\s5\.0/')) $this->result_os_version = '2000';
350+
if ($this->match_ua('/Windows\sXP/')) $this->result_os_version = 'XP';
351351
if ($this->match_ua('/WinNT4\.0/')) $this->result_os_version = 'NT 4.0';
352+
if ($this->match_ua('/Windows\sVista/')) $this->result_os_version = 'Vista';
353+
if ($this->match_ua('/Windows\s7/')) $this->result_os_version = '7';
354+
if ($this->match_ua('/Windows\s8/')) $this->result_os_version = '8';
355+
if ($this->match_ua('/Windows\s8.1/')) $this->result_os_version = '8.1';
356+
if ($this->match_ua('/Windows\s10/')) $this->result_os_version = '10';
357+
if ($this->match_ua('/Windows\s11/')) $this->result_os_version = '11';
352358
}
353359
if (!empty($this->result_os_version)) $this->result_os_title = 'Windows '.$this->result_os_version;
354360
else $this->result_os_title = 'Windows (unknown version)';
@@ -402,7 +408,7 @@ private function getResult()
402408
}
403409
else
404410
{
405-
$this->result_os_title = 'MacOS (classic old)';
411+
$this->result_os_title = 'MacOS';
406412
}
407413
$this->result_os_family = 'macintosh';
408414
$os_need_continue = FALSE;
@@ -834,7 +840,7 @@ private function getResult()
834840
if (!empty($matches[2])) $this->result_browser_version = (int)$matches[2];
835841
$this->result_browser_chromium_version = $this->result_browser_version;
836842
if ($this->match_ua('CriOS/')) $this->result_browser_chromium_version = 0;
837-
if ($this->match_ua('/Gecko\)\s(Chrome|CrMo)\/(\d+\.\d+\.\d+\.\d+)\s(?:Mobile)?(?:\/[.0-9A-Za-z]+\s|\s)?Safari\/[.0-9]+$/') && !$this->match_ua('SalamWeb') && !$this->match_ua('Valve Steam')) $this->result_browser_chrome_original = 1;
843+
if ($this->match_ua('/Gecko\)\s(Chrome|CrMo)\/(\d+\.\d+\.\d+\.\d+)\s(?:Mobile)?(?:\/[.0-9A-Za-z]+\s|\s)?Safari\/[.0-9]+$/') && !$this->match_ua('SalamWeb') && !$this->match_ua(' Valve ')) $this->result_browser_chrome_original = 1;
838844
}
839845

840846
// Firefox
@@ -857,7 +863,7 @@ private function getResult()
857863
$browser_list[] = array('Opera', ' OPR/', '/OPR\/(\d+)/', '1', 'Opera Mini|OPiOS|OPT/|OPRGX/|AlohaBrowser');
858864
$browser_list[] = array('Opera', 'Opera', '/Opera.*Version\/([0-9]+\.[0-9]+)/', '1', 'Opera Mini|OPiOS|OPT/|InettvBrowser/');
859865
$browser_list[] = array('Opera', 'Opera', '/Opera(\s|\/)([0-9]+\.[0-9]+)/', '2', 'Opera Mini|OPiOS|OPT/|InettvBrowser/');
860-
$browser_list[] = array('UC Browser', 'UBrowser|UCBrowser|UCMini', '/(UBrowser|UCBrowser|UCMini)\/([0-9]+\.[0-9]+)/', '2', 'UCTurbo');
866+
$browser_list[] = array('UC Browser', 'UBrowser|UCBrowser|UCMini', '/(UBrowser|UCBrowser|UCMini)\/([0-9]+\.[0-9]+)/', '2', 'UCTurbo|AliApp');
861867
$browser_list[] = array('UC Browser Turbo', 'UCTurbo/', '/UCTurbo\/([0-9]+\.[0-9]+)/', '1', '');
862868
$browser_list[] = array('Puffin', 'Puffin/', '/Puffin\/([0-9]+\.[0-9]+)/', '1', '');
863869
$browser_list[] = array('Vivaldi', 'Vivaldi/', '/Vivaldi\/([0-9]+\.[0-9]+)/', '1', '');
@@ -963,7 +969,7 @@ private function getResult()
963969

964970
// Chromium based browsers
965971

966-
$browser_list[] = array('Avast Secure Browser', 'Avast/', '/Avast\/([0-9]+)/', '1', '');
972+
$browser_list[] = array('Avast Browser', 'Avast/', '/Avast\/([0-9]+)/', '1', '');
967973
$browser_list[] = array('AVG Secure Browser', 'AVG/', '/AVG\/([0-9]+)/', '1', '');
968974
$browser_list[] = array('CCleaner Browser', 'CCleaner/', '/CCleaner\/([0-9]+)/', '1', '');
969975
$browser_list[] = array('Comodo Dragon', 'Dragon/', '/Dragon\/([0-9]+)/', '1', 'IceDragon');
@@ -1025,8 +1031,8 @@ private function getResult()
10251031
$browser_list[] = array('Fluid', 'Fluid/', '/Fluid\/([0-9]+\.[0-9]+)/', '1', '');
10261032
$browser_list[] = array('Arora', 'Arora/', '/Arora\/([0-9]+\.[0-9]+)/', '1', '');
10271033
$browser_list[] = array('Artis Browser', 'ArtisBrowser/', '/ArtisBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1028-
$browser_list[] = array('Valve Steam Client', 'Valve Steam Client', '/Valve\sSteam\sClient/', '1', '');
1029-
$browser_list[] = array('Valve Steam Game Overlay', 'Valve Steam GameOverlay', '/Valve\sSteam\sGameOverlay/', '1', '');
1034+
$browser_list[] = array('Steam Client', ' Valve ', '/Valve\s(|Steam\s)Client/', '1', 'Tenfoot');
1035+
$browser_list[] = array('Steam Overlay', ' Valve ', '/Valve\sSteam\sGameOverlay/', '1', 'Tenfoot|Client/');
10301036
$browser_list[] = array('Rekonq', ' rekonq', '/rekonq\/([0-9]+\.[0-9]+)/', '1', '');
10311037
$browser_list[] = array('Odyssey Web Browser', 'Odyssey Web Browser', '/OWB\/([0-9]+\.[0-9]+)/', '1', '');
10321038
$browser_list[] = array('Safari SDK', '/^Safari\/[.0-9]+\sCFNetwork\/[.0-9]+\sDarwin\/[.0-9]+/', '/Safari\//', '1', '');
@@ -1035,6 +1041,7 @@ private function getResult()
10351041
$browser_list[] = array('Firefox', 'GranParadiso/', '/GranParadiso\/([0-9]+)/', '1', '');
10361042
$browser_list[] = array('Firefox', 'Shiretoko/', '/Shiretoko\/([0-9]+)/', '1', '');
10371043
$browser_list[] = array('Firefox', 'Namoroka/', '/Namoroka\/([0-9]+)/', '1', '');
1044+
$browser_list[] = array('iTunes App', 'iTunes/', '/iTunes\/([0-9]+\.[0-9]+)/', '1', '');
10381045

10391046
foreach($browser_list as $browser_list_va)
10401047
{
@@ -1096,8 +1103,8 @@ private function getResult()
10961103
{
10971104
// Mobile browsers with detectable versions
10981105

1099-
$browser_list[] = array('Safari Mobile', '/(iPhone|iphone|iPad|iPod).*AppleWebKit\/[.0-9]+\s\(KHTML,\slike\sGecko\)\s.*Version\/[.0-9]+\sMobile\//', '/Version\/([0-9]+\.[0-9]+)(|\.[0-9]+)\sMobile\//', '1', 'RDDocuments|AlohaBrowser|DuckDuckGo|MiuiBrowser|Snapchat|NAVER(inapp;');
1100-
$browser_list[] = array('Safari Mobile', '/(Intel\sMac\sOS\sX).*AppleWebKit\/.*Version\/[.0-9]+\s(?:|Mobile\/\w+\s)Safari\/[.0-9A-Za-z]+(|\/[0-9]+|\s\(.*\))+$/', '/Version\/([0-9]+\.[0-9]+)(|\.[0-9]+)/', '1', 'RDDocuments|AlohaBrowser|DuckDuckGo|MiuiBrowser|Snapchat|NAVER(inapp;');
1106+
$browser_list[] = array('Safari Mobile', '/(iPhone|iphone|iPad|iPod).*AppleWebKit\/[.0-9]+\s\(KHTML,\slike\sGecko\)\s.*Version\/[.0-9]+\sMobile\//', '/Version\/([0-9]+\.[0-9]+)(|\.[0-9]+)\sMobile\//', '1', 'RDDocuments|AlohaBrowser|DuckDuckGo|MiuiBrowser|Snapchat|NAVER(inapp;|1Password');
1107+
$browser_list[] = array('Safari Mobile', '/(Intel\sMac\sOS\sX).*AppleWebKit\/.*Version\/[.0-9]+\s(?:|Mobile\/\w+\s)Safari\/[.0-9A-Za-z]+(|\/[0-9]+|\s\(.*\))+$/', '/Version\/([0-9]+\.[0-9]+)(|\.[0-9]+)/', '1', 'RDDocuments|AlohaBrowser|DuckDuckGo|MiuiBrowser|Snapchat|NAVER(inapp;|1Password');
11011108
$browser_list[] = array('Android Browser', '/Android.*Version\/[.0-9]+\s(?:Mobile\s)?Safari\/[.0-9]+(|\-[0-9]+)$/', '/Android.*Version\/([0-9]+\.[0-9]+)/', '1', 'Chrome/');
11021109
$browser_list[] = array('Android Browser', 'Dalvik/', '/Dalvik\/([.0-9]+)\s\(Linux;\sU;\sAndroid\s/', '2', 'Chrome/');
11031110
$browser_list[] = array('Samsung Browser', 'SamsungBrowser', '/SamsungBrowser\/([0-9]+\.[0-9]+)/', '1', 'CrossApp');
@@ -1109,11 +1116,12 @@ private function getResult()
11091116
$browser_list[] = array('DuckDuckGo', 'DuckDuckGo/', '/DuckDuckGo\/([0-9]+)/', '1', '');
11101117
$browser_list[] = array('MIUI Browser', 'MiuiBrowser/', '/MiuiBrowser\/([0-9]+\.[0-9]+)/', '1', '');
11111118
$browser_list[] = array('Mint Browser', 'Mint Browser/', '/Mint\sBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1112-
$browser_list[] = array('Avast Browser Mobile', 'AvastSecureBrowser/', '/AvastSecureBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1119+
$browser_list[] = array('Avast Browser', 'AvastSecureBrowser/', '/AvastSecureBrowser\/([0-9]+\.[0-9]+)/', '1', '');
11131120
$browser_list[] = array('Google App', '/(iPhone|iphone|iPad|iPod).*\)\sGSA\/([0-9]+)/', '/(iPhone|iphone|iPad|iPod).*\)\sGSA\/([0-9]+)/', '2', '');
11141121
$browser_list[] = array('Google App', '/\sGSA\//', '/\sGSA\/([0-9]+)/', '1', '');
1115-
$browser_list[] = array('Facebook App', 'FBAV/|FBSV/', '/FBAV\/([0-9]+)\./', '1', '');
1122+
$browser_list[] = array('Facebook App', 'FBAV/|FBSV/', '/(FBAV|FBSV)\/([0-9]+)\./', '2', 'FBAN/Messenger|FB_IAB/MESSENGER');
11161123
$browser_list[] = array('Instagram App', 'Instagram', '/Instagram\s([0-9]+)\./', '1', '');
1124+
$browser_list[] = array('Facebook Messenger', 'FBAN/Messenger|FB_IAB/MESSENGER', '/(FBAV|FBSV)\/([0-9]+)\./', '2', '');
11171125
$browser_list[] = array('Snapchat', 'Snapchat', '/\sSnapchat\/([0-9]+\.[0-9]+)/', '1', '');
11181126
$browser_list[] = array('WhatsApp', 'WhatsApp', '/WhatsApp\/([0-9]+\.[0-9]+)/', '1', '');
11191127
$browser_list[] = array('Viber', 'Viber/', '/Viber\/([0-9]+\.[0-9]+)/', '1', '');
@@ -1134,7 +1142,7 @@ private function getResult()
11341142
$browser_list[] = array('Surf Browser', 'SurfBrowser/', '/SurfBrowser\/([0-9]+\.[0-9]+)/', '1', '');
11351143
$browser_list[] = array('Phoenix Browser', 'PHX/', '/PHX\/([0-9]+\.[0-9]+)/', '1', '');
11361144
$browser_list[] = array('CM Mobile', 'ACHEETAHI', '/Chrome\/([0-9]+)/', '1', '');
1137-
$browser_list[] = array('Bing Search App', 'BingWeb/', '/BingWeb\/([0-9]+\.[0-9]+)/', '1', '');
1145+
$browser_list[] = array('Bing App', ' BingWeb', '/BingWeb\/([0-9]+\.[0-9]+)/', '1', '');
11381146
$browser_list[] = array('Firefox Klar', 'Klar/', '/Klar\/([0-9]+\.[0-9]+)/', '1', '');
11391147
$browser_list[] = array('Super Fast Browser', 'SFBrowser|tssomas', '/(SFBrowser|tssomas)\/([0-9]+\.[0-9]+)/', '2', '');
11401148
$browser_list[] = array('Tenta Browser', 'Tenta/', '/Tenta\/([0-9]+\.[0-9]+)/', '1', '');
@@ -1180,6 +1188,11 @@ private function getResult()
11801188
$browser_list[] = array('Line App', ' Line/', '/\sLine\/([0-9]+\.[0-9]+)/', '1', '');
11811189
$browser_list[] = array('QQ App', ' QQ/', '/\sQQ\/([0-9]+\.[0-9]+)/', '1', '');
11821190
$browser_list[] = array('GNews App', ' GNews ', '/\sGNews\s.*\/([0-9]+\.[0-9]+)/', '1', '');
1191+
$browser_list[] = array('1Password App', '1Password', '/\s1Password\/([0-9]+\.[0-9]+)/', '1', '');
1192+
$browser_list[] = array('Pinterest App', 'Pinterest', '/Pinterest/', '1', '');
1193+
$browser_list[] = array('Twitter App', ' Twitter', '/Twitter/', '1', '');
1194+
$browser_list[] = array('Ali App', ' AliApp', '/\sAliApp/', '1', '');
1195+
$browser_list[] = array('Alipay', 'AlipayClient', '/AlipayClient\/([0-9]+\.[0-9]+)/', '1', '');
11831196
$browser_list[] = array('Samsung CrossApp', 'CrossApp/', '/CrossApp\/([0-9]+\.[0-9]+)/', '1', '');
11841197
$browser_list[] = array('Diigo Browser', 'DiigoBrowser', '/DiigoBrowser/', '1', '');
11851198

@@ -1285,6 +1298,7 @@ private function getResult()
12851298
$matches[1] = str_replace('com.apple.Notes.', '', $matches[1]);
12861299
$matches[1] = str_replace('com.apple.mobilenotes.', '', $matches[1]);
12871300
$this->result_browser_name = $matches[1].' App';
1301+
if ($this->result_browser_name === 'Browser App') $this->result_browser_name = 'Darwin Browser';
12881302
$darwin_app = TRUE;
12891303
}
12901304
}
@@ -1305,20 +1319,24 @@ private function getResult()
13051319
if ($this->result_browser_chrome_original == 0 && $this->result_browser_chromium_version != 0 && $this->match_ua('/like\sGecko\)\sVersion\/[.0-9]+\sChrome\/[.0-9]+\s/')) $this->result_browser_android_webview = 1;
13061320
}
13071321

1308-
// Safari WebView
1322+
// WebKit WebView
13091323

13101324
if ($this->result_ios)
13111325
{
1312-
$safari_webview = FALSE;
1326+
$webkit_webview = FALSE;
13131327

1314-
if ($this->result_browser_name === 'unknown' && !$this->match_ua('Safari|iCabMobile') && $this->match_ua('/\s\((iPhone|iphone|iPad|iPod);.*\)\sAppleWebKit\/[.0-9]+\s\(KHTML\,\slike Gecko\)\sMobile\//')) $safari_webview = TRUE;
1315-
if ($this->result_browser_name === 'unknown' && $this->match_ua('MobileSafari/') && $this->match_ua('CFNetwork/')) $safari_webview = TRUE;
1328+
if (!$this->match_ua('CriOS|FxiOS|OPiOS') && $this->match_ua('/\s\((iPhone|iphone|iPad|iPod);.*\)\sAppleWebKit\/[.0-9]+\s\(KHTML\,\slike Gecko\)\s(?!Version).*Mobile\/([0-9A-Z]+)\s/')) $webkit_webview = TRUE;
1329+
if ($this->result_browser_name === 'unknown' && $this->match_ua('MobileSafari/') && $this->match_ua('CFNetwork/')) $webkit_webview = TRUE;
13161330

1317-
if ($safari_webview)
1331+
if ($webkit_webview)
13181332
{
13191333
$this->result_browser_ios_webview = 1;
1320-
$this->result_browser_version = 0;
1321-
$this->result_browser_name = 'Mobile Safari WebView';
1334+
1335+
if ($this->result_browser_name === 'unknown')
1336+
{
1337+
$this->result_browser_name = 'WebKit WebView';
1338+
$this->result_browser_version = 0;
1339+
}
13221340
}
13231341
}
13241342
}
@@ -1336,7 +1354,7 @@ private function getResult()
13361354

13371355
// Check and correct browser version anomaly
13381356

1339-
if (intval($this->result_browser_version)>150 && !$this->match_ua('FBAV/|FBSV/|GSA/|Instagram')) $this->result_browser_version = 0;
1357+
if (intval($this->result_browser_version)>200 && !$this->match_ua('FBAV/|FBSV/|GSA/|Instagram')) $this->result_browser_version = 0;
13401358

13411359
// Set Browser title
13421360

@@ -1347,16 +1365,22 @@ private function getResult()
13471365

13481366
$browsers_without_versions = array();
13491367
$browsers_without_versions[] = 'Android Browser';
1350-
$browsers_without_versions[] = 'Mobile Safari WebView';
1368+
$browsers_without_versions[] = 'WebKit WebView';
13511369
$browsers_without_versions[] = 'Safari SDK';
13521370
$browsers_without_versions[] = 'Playstation Browser';
13531371
$browsers_without_versions[] = 'OmniWeb';
1354-
$browsers_without_versions[] = 'Valve Steam Client';
1355-
$browsers_without_versions[] = 'Valve Steam Game Overlay';
1372+
$browsers_without_versions[] = 'Steam Client';
1373+
$browsers_without_versions[] = 'Steam Overlay';
13561374
$browsers_without_versions[] = 'Maple';
13571375
$browsers_without_versions[] = 'Espial';
13581376
$browsers_without_versions[] = 'Diigo Browser';
13591377
$browsers_without_versions[] = 'IceWeasel';
1378+
$browsers_without_versions[] = 'Facebook App';
1379+
$browsers_without_versions[] = 'Twitter App';
1380+
$browsers_without_versions[] = 'Bing App';
1381+
$browsers_without_versions[] = 'Pinterest App';
1382+
$browsers_without_versions[] = 'Ali App';
1383+
$browsers_without_versions[] = 'Alipay App';
13601384

13611385
if (in_array($this->result_browser_name, $browsers_without_versions) || isset($darwin_app))
13621386
{
@@ -1368,6 +1392,9 @@ private function getResult()
13681392

13691393
if (strpos($this->result_browser_name, 'unknown') !== FALSE) $this->result_browser_title = 'unknown';
13701394
if ($this->result_browser_version == NULL) $this->result_browser_version = 0;
1395+
1396+
// EdgeHTML browser should not be detected as a Chromium engine
1397+
if ($this->result_browser_name === 'Edge' && $this->result_browser_version >= 12 && $this->result_browser_version <= 18) $this->result_browser_chromium_version = 0;
13711398

13721399
if ($this->get_mode === 'browser') return NULL;
13731400

@@ -1395,7 +1422,7 @@ private function getResult()
13951422

13961423
// MediaPlayer
13971424

1398-
if ($this->match_ua('iPod|iTunes|AlexaMediaPlayer|AppleCoreMedia')) $this->result_device_type = 'mediaplayer';
1425+
if ($this->match_ua('iPod|AlexaMediaPlayer|AppleCoreMedia')) $this->result_device_type = 'mediaplayer';
13991426

14001427
// Car
14011428

0 commit comments

Comments
 (0)