PHP User Agent Parser
Requirements
- PHP >= 5.4.0
Download
The script is available over on GitHub or via Composer:
$ composer require 'donatj/phpuseragentparser'
Usage
The original procedural use is as simple as:
<?php
// v0 style global function - @deprecated
$uaInfo = parse_user_agent();
// or
// modern namespaced function
$uaInfo = donatj\UserAgent\parse_user_agent();
echo $uaInfo[donatj\UserAgent\PLATFORM] . PHP_EOL;
echo $uaInfo[donatj\UserAgent\BROWSER] . PHP_EOL;
echo $uaInfo[donatj\UserAgent\BROWSER_VERSION] . PHP_EOL;
The new object oriented wrapper form:
<?php
use donatj\UserAgent\UserAgentParser;
$parser = new UserAgentParser();
// object-oriented call
$ua = $parser->parse();
// or
// command style invocation
$ua = $parser();
echo $ua->platform() . PHP_EOL;
echo $ua->browser() . PHP_EOL;
echo $ua->browserVersion() . PHP_EOL;
Currently Detected Platforms
see: List of Detected Browsers
Comment by: Valery on
π Valery's Gravatar
Can you add platform version support?
For example WinXP, Win7, Win8, etc.
And processor detail 32/64 bit.
Can you add platform version support?
For example WinXP, Win7, Win8, etc.
And processor detail 32/64 bit.
Comment by: RuuRd on
π RuuRd's Gravatar
thanks Donat for your great parse_user_agent function! I read through your code and I have a few questions. as far as I know array_intersect never returns a boolean .....
thanks Donat for your great parse_user_agent function! I read through your code and I have a few questions. as far as I know array_intersect never returns a boolean .....
if( $keys = array_intersect($priority, $result['platform']) ) {
assignment to $key instead of evaluation:
if( ( $data['platform'] == 'Android' && !($key = 0) ) ||
some $key = array_search() evaluation to β!== falseβ seem to be missing ..
like
elseif( $key = array_search( 'Safari', $result['browser'] ) ) {
Your function works well though!
Comment by: Jesse G. Donat on
π Jesse G. Donat's Gravatar
PHP uses implicit type conversion, whereas an empty array is false-y and one containing any value is truth-y, and my code is simply taking advantage of this feature of the language to save on code.
PHP uses implicit type conversion, whereas an empty array is false-y and one containing any value is truth-y, and my code is simply taking advantage of this feature of the language to save on code.
Comment by: Tomas on
π Tomas's Gravatar
Thanks for this. But it throws error when I try to validate my site with http://html5.validator.nu
[2013-07-09 23:39:06] Notice: 8. Message: Undefined offset: 0. In file Request.class.php at line 241. Browser: v (Unknown) 92.243.10.170
[2013-07-09 23:39:06] Notice: 8. Message: Undefined offset: 0. In file Request.class.php at line 242. Browser: v (Unknown) 92.243.10.170
[2013-07-09 23:42:30] Notice: 8. Message: Undefined offset: 0. In file Request.class.php at line 257. Browser: v (Unknown) 92.243.10.170
[2013-07-09 23:42:30] Notice: 8. Message: Undefined offset: 0. In file Request.class.php at line 275. Browser: v (Unknown) 92.243.10.170
first two errors:
$data['browser'] = $result['browser'][0];
$data['version'] = $result['version'][0];
and others in:
} elseif($result['browser'][0] == 'AppleWebKit') {
} elseif($result['browser'][0] == 'MSIE') {
Thanks for this. But it throws error when I try to validate my site with http://html5.validator.nu
[2013-07-09 23:39:06] Notice: 8. Message: Undefined offset: 0. In file Request.class.php at line 241. Browser: v (Unknown) 92.243.10.170
[2013-07-09 23:39:06] Notice: 8. Message: Undefined offset: 0. In file Request.class.php at line 242. Browser: v (Unknown) 92.243.10.170
[2013-07-09 23:42:30] Notice: 8. Message: Undefined offset: 0. In file Request.class.php at line 257. Browser: v (Unknown) 92.243.10.170
[2013-07-09 23:42:30] Notice: 8. Message: Undefined offset: 0. In file Request.class.php at line 275. Browser: v (Unknown) 92.243.10.170
first two errors:
$data['browser'] = $result['browser'][0];
$data['version'] = $result['version'][0];
and others in:
} elseif($result['browser'][0] == 'AppleWebKit') {
} elseif($result['browser'][0] == 'MSIE') {
Comment by: Jesse G. Donat on
π Jesse G. Donat's Gravatar
Ideally you should not be running with notices turned on on production. I will look into fixing these, but notice free code in PHP is very rare.
Considering hiding notices using http://php.net/manual/en/function.error-reporting.php
Ideally you should not be running with notices turned on on production. I will look into fixing these, but notice free code in PHP is very rare.
Considering hiding notices using http://php.net/manual/en/function.error-reporting.php
Comment by: farzin on
π farzin's Gravatar
hi , i have failed to use your script.
i have uploaded the whole github directory.
Then i'm running UserAgentParserTest.php and i get nothing.
i use this code in another php and i get nothing again :(
require 'UserAgentParser.php';
$ua_info = parse_user_agent();
print_r($ua_info);
echo "farzin".$ua_info;
Comment by: farzin on
π farzin's Gravatar
i finally got it working by adding this codes and its working fine now . thank you for sharing this. :
$agent = $_SERVER['HTTP_USER_AGENT'];
echo $agent.'<br />';
echo '<h1>Test Suite</h1>';
$parsedagent = parse_user_agent($agent);
echo "<pre>";
print_r($parsedagent);
echo "</pre>";
Comment by: dac on
π dac's Gravatar
Hey, very nice script, but to be more precise on distinguish Opera and Opera Next, just add one more elseif rather than using OR when checking 'OPR' || 'Opera'. IF 'OPR' then it is Opera Next, IF 'Opera' then it is Opera. This is only PHP script that scrapes right version of Opera, weather it is Opera Next or Opera. It is not a bug, but it is more precise. :)
Hey, very nice script, but to be more precise on distinguish Opera and Opera Next, just add one more elseif rather than using OR when checking 'OPR' || 'Opera'. IF 'OPR' then it is Opera Next, IF 'Opera' then it is Opera. This is only PHP script that scrapes right version of Opera, weather it is Opera Next or Opera. It is not a bug, but it is more precise. :)
Comment by: ~BoogL~ on
π ~BoogL~'s Gravatar
May be i'm wrong, but i think it's wrong detection on this agents:
Mozilla/5.0 (Linux; Android 4.0.4; GT-P5100 Build/IMM76D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.90 Safari/537.36
User Agent Returned: Chrome version 537.36 on Android but not version 27.0.1453.90
Opera/9.80 (J2ME/MIDP; Opera Mini/4.4.28000/30.3061; U; ru) Presto/2.8.119 Version/11.10
User Agent Returned: Opera version 11.10 but not Opera Mini 4.4.28000
And i'm not shure that Mozilla/5.0 (Linux; U; Android 4.1.1; ru-ru; A701 Build/JRO03H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30
is Chrome version 4.0
May be i'm wrong, but i think it's wrong detection on this agents:
Mozilla/5.0 (Linux; Android 4.0.4; GT-P5100 Build/IMM76D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.90 Safari/537.36
User Agent Returned: Chrome version 537.36 on Android but not version 27.0.1453.90
Opera/9.80 (J2ME/MIDP; Opera Mini/4.4.28000/30.3061; U; ru) Presto/2.8.119 Version/11.10
User Agent Returned: Opera version 11.10 but not Opera Mini 4.4.28000
And i'm not shure that Mozilla/5.0 (Linux; U; Android 4.1.1; ru-ru; A701 Build/JRO03H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30
is Chrome version 4.0
Comment by: Jesse G. Donat on
π Jesse G. Donat's Gravatar
You are right, I have corrected this in the latest release v0.1.5 and included a test specifically for that UA string.
You are right, I have corrected this in the latest release v0.1.5 and included a test specifically for that UA string.
Comment by: Mark on
π Mark's Gravatar
Mozilla/5.0 (Linux; Android 4.2.2; de-at; SAMSUNG GT-I9195/I9195XXUAMF6 Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Version/1.0 Chrome/18.0.1025.308 Mobile Safari/535.19
Here is a problem... it returns Android Version 1.0
Mozilla/5.0 (Linux; Android 4.2.2; de-at; SAMSUNG GT-I9195/I9195XXUAMF6 Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Version/1.0 Chrome/18.0.1025.308 Mobile Safari/535.19
Here is a problem... it returns Android Version 1.0
Comment by: Kalla on
π Kalla's Gravatar
Code is working fine. But how i get complete platform ex. Windows XP, Windows Vista, Windows 7 or Windows 8
Code is working fine. But how i get complete platform ex. Windows XP, Windows Vista, Windows 7 or Windows 8
Comment by: Varuzhan Kankanyan on
π Varuzhan Kankanyan's Gravatar
Hello, I think will be reasonable to add an option to return also device type ( Desktop, Mobile, Console). Bellow the code to be added:
$platforms = array(
'desktop' => array('Windows','Linux','Macintosh','Chrome OS'),
'mobile' => array('Android','iPhone','iPad','Windows Phone OS','Kindle','Kindle Fire','BlackBerry','Playbook'),
'console' => array('Nintendo 3DS','Nintendo Wii','Nintendo WiiU','PlayStation 3','PlayStation Vita','Xbox 360')
);
foreach($platforms as $k=>$v){
foreach($v as $pl){if($pl == $platform){$device = $k;break;}
}
}
return array( 'device' => $device, 'platform' => $platform, 'browser' => $browser, 'version' => $version );
Comment by: Jesse G. Donat on
π Jesse G. Donat's Gravatar
I'm sorry but I'm not interested in implementing anything along these lines right now. I think you would likely be better off simply creating a function that calls my function doing your desired analysis.
My goal is to keep this more of a strict parser and not an interpreter.
I really want to avoid feature creep.
I'm sorry but I'm not interested in implementing anything along these lines right now. I think you would likely be better off simply creating a function that calls my function doing your desired analysis.
My goal is to keep this more of a strict parser and not an interpreter.
I really want to avoid feature creep.
Comment by: Ueli on
π Ueli's Gravatar
Thanks a lot for this great piece of code.
Just a very minor suggestion for the documentation. I wasn't sure if the currently detected items are effectively return values, or if they are just listed in a descriptive style. So I went into the code to be sure. This would be more obvious if the items were enclosed by quotes, for a list like
o Mobile
- 'Android'
- 'Windows Phone OS'
- 'Kindle Fire'
Thanks a lot for this great piece of code.
Just a very minor suggestion for the documentation. I wasn't sure if the currently detected items are effectively return values, or if they are just listed in a descriptive style. So I went into the code to be sure. This would be more obvious if the items were enclosed by quotes, for a list like
o Mobile
- 'Android'
- 'Windows Phone OS'
- 'Kindle Fire'
Comment by: Const on
π Const's Gravatar
Hi, what about the new Vivaldi browser?
The string is: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.89 Vivaldi/1.0.83.38 Safari/537.36 and is identified as Chrome 40.
Hi, what about the new Vivaldi browser?
The string is: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.89 Vivaldi/1.0.83.38 Safari/537.36 and is identified as Chrome 40.
Comment by: Ben on
π Ben's Gravatar
Hi - many thanks for this extremely useful tool. I was wondering if there was a way to further differentiate device types: at the moment, a distinction is made between "Desktop" and "Mobile" devices - could the latter be further split into "Phone" and "Tablet" devices? I know it's possible to tell iPhones and iPads apart, but is there any reliable way of doing similar for Androids? Can we tell Chrome on an Android tablet from Chrome on an Android phone?
Hi - many thanks for this extremely useful tool. I was wondering if there was a way to further differentiate device types: at the moment, a distinction is made between "Desktop" and "Mobile" devices - could the latter be further split into "Phone" and "Tablet" devices? I know it's possible to tell iPhones and iPads apart, but is there any reliable way of doing similar for Androids? Can we tell Chrome on an Android tablet from Chrome on an Android phone?
Comment by: Cli on
π Cli's Gravatar
This is pretty awesome as it is right now, but could you include Operating system versions as well? E.g. Windows 7 SP1, Windows 8, Windows Vista, Android 4, Android 5 etc?
This is pretty awesome as it is right now, but could you include Operating system versions as well? E.g. Windows 7 SP1, Windows 8, Windows Vista, Android 4, Android 5 etc?
Comment by: Jesse G. Donat on
π Jesse G. Donat's Gravatar
JOe, not true! It's actually extensively tested to work from PHP 5.3 all the way through PHP 7 - including HHVM.
See: https://travis-ci.org/donatj/PhpUserAgent
If you had left an actual email address I'd have been happy to help you resolve your issues. Alas.
JOe, not true! It's actually extensively tested to work from PHP 5.3 all the way through PHP 7 - including HHVM.
See: https://travis-ci.org/donatj/PhpUserAgent
If you had left an actual email address I'd have been happy to help you resolve your issues. Alas.
Comment by: Martin on
π Martin's Gravatar
Thanks for this functionality, it's simple, with low footprint, and works.
Really appreciated. Keep up the good work.
Thanks for this functionality, it's simple, with low footprint, and works.
Really appreciated. Keep up the good work.
Comment by: Philippe on
π Philippe's Gravatar
Hi, great script, thank you very much.
Just one thing, it looks like Opera Neon is not detected correctly
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.21 Safari/537.36 MMS/1.0.2531.0
Hi, great script, thank you very much.
Just one thing, it looks like Opera Neon is not detected correctly
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.21 Safari/537.36 MMS/1.0.2531.0
Comment by: Jesse G. Donat on
π Jesse G. Donat's Gravatar
They are making it hard to detect on purpose because they want to be detected as Chrome.
While I can update the code to sniff it out since it doesn't indicate what it actually is, it's not a mainstream enough browser to justify the additional code. Worldwide usage is basically nil.
It's in their own words a "Concept Browser". If and when it becomes anything more than a concept, I will gladly support it, but until thenβ¦
They are making it hard to detect on purpose because they want to be detected as Chrome.
While I can update the code to sniff it out since it doesn't indicate what it actually is, it's not a mainstream enough browser to justify the additional code. Worldwide usage is basically nil.
It's in their own words a "Concept Browser". If and when it becomes anything more than a concept, I will gladly support it, but until thenβ¦
Comment by: Gonzo Far on
π Gonzo Far's Gravatar
Thank you for you work.
Why am I getting these errors?
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in C:\dev\UserAgentParser.php on line 23
Parse error: syntax error, unexpected ':' in C:\dev\UserAgentParser.php on line 73
Thank you for you work.
Why am I getting these errors?
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in C:\dev\UserAgentParser.php on line 23
Parse error: syntax error, unexpected ':' in C:\dev\UserAgentParser.php on line 73
Comment by: Jesse G Donat on
π Jesse G Donat's Gravatar
Sorry I didn't see this comment until now. It would appear you are running a very old PHP version - pre namespaces.
My library supports all the way back to PHP 5.3.0 which is 11 years old. You're running older something older than that.
It's probably time to upgrade.
Sorry I didn't see this comment until now. It would appear you are running a very old PHP version - pre namespaces.
My library supports all the way back to PHP 5.3.0 which is 11 years old. You're running older something older than that.
It's probably time to upgrade.
Comment by: Aishwarya Easwar on
π Aishwarya Easwar's Gravatar
Thank you for an amazing user agent parser. I would like to know if the following browser versions can be detected:
1. Chrome 26.0.1410.43, 31.0.1650.57, 27.0.1453.116, 16.0.912.63, 23.0.1271.97, 22.0.1229.79, 28.0.1500.71, 5.0.375.53, 11.0.696.68, 14.0.835.187, 10.0.648.133, 12.0.742.112
2. MSIE 7.0, 6.0, 8.0
3. Mobile Safari - older versions
4. Firefox 22, 31, 23, 3.6.11, 3.6.7, 5, 4.0.1, 30, 9.0.1, 32, 27, 2.0.0.10
5. Mobile_Chrome 28.0.1500.94, R83-13020.67.0, R84-13099.110.0, R85-13310.59.0
6. Mobile Safari - older versions
Thank you for an amazing user agent parser. I would like to know if the following browser versions can be detected:
1. Chrome 26.0.1410.43, 31.0.1650.57, 27.0.1453.116, 16.0.912.63, 23.0.1271.97, 22.0.1229.79, 28.0.1500.71, 5.0.375.53, 11.0.696.68, 14.0.835.187, 10.0.648.133, 12.0.742.112
2. MSIE 7.0, 6.0, 8.0
3. Mobile Safari - older versions
4. Firefox 22, 31, 23, 3.6.11, 3.6.7, 5, 4.0.1, 30, 9.0.1, 32, 27, 2.0.0.10
5. Mobile_Chrome 28.0.1500.94, R83-13020.67.0, R84-13099.110.0, R85-13310.59.0
6. Mobile Safari - older versions
Comment by: Jesse Donat on
π Jesse Donat's Gravatar
Aishwarya Easwar - I replied to your email before you commented this - did you receive my response?
Aishwarya Easwar - I replied to your email before you commented this - did you receive my response?
Comment by: Scott on
π Scott's Gravatar
Your code examples are missing the namespace. You need to add:
use donatj\UserAgent\UserAgentParser;
Your code examples are missing the namespace. You need to add:
use donatj\UserAgent\UserAgentParser;
Comment by: Jesse G. Donat on
π Jesse G. Donat's Gravatar
Thanks for the heads up. I've fixed it here as well as in the README file.
Thanks for the heads up. I've fixed it here as well as in the README file.
