Space Cat, Prince Among Thieves

PHP User Agent Parser

Demo You are running CCBot version 2.0 on
CCBot/2.0 (http://commoncrawl.org/faq/)
Try It!


Requirements

  • PHP 5.3.0+

I do not support PHP 5.2. If you are receiving a Parse error: syntax error, unexpected T_FUNCTION you are likely running php 5.2 or older. PHP 5.2 is not receiving updates, and you simply should not be running it in production. It is dangerous as there are known security flaws. You should upgrade ASAP. PHP 5.3 came out over fives years ago, and there is no reason to be running such an old version.

Download

The script is availible over on Github or via Composer:

{
    "require": {
        "donatj/phpuseragentparser": "*"
    }
}

Sample Usage

$ua_info = parse_user_agent();
/*
array(
    'platform' => '[Detected Platform]',
    'browser'  => '[Detected Browser]',
    'version'  => '[Detected Browser Version]',
);
*/

Currently Detected Platforms

  • Desktop
    • Windows
    • Linux
    • Macintosh
    • Chrome OS
  • Mobile
    • Android
    • iPhone
    • iPad
    • Windows Phone OS
    • Kindle
    • Kindle Fire
    • BlackBerry
    • Playbook
  • Console
    • Nintendo 3DS
    • New Nintendo 3DS
    • Nintendo Wii
    • Nintendo WiiU
    • PlayStation 3
    • PlayStation 4
    • PlayStation Vita
    • Xbox 360
    • Xbox One

Currently Detected Browsers

  • Android Browser
  • BlackBerry Browser
  • Camino
  • Kindle / Silk
  • Firefox / Iceweasel
  • Safari
  • Internet Explorer
  • IEMobile
  • Chrome
  • Opera
  • Midori
  • Vivaldi
  • Lynx
  • Wget
  • Curl


Comment by: ling on

ling GravatarThank you very much !!

Comment by: dankoi on

dankoi GravatarThank you so much!
Great job!

Comment by: Valery on

Valery GravatarCan you add platform version support?
For example WinXP, Win7, Win8, etc.
And processor detail 32/64 bit.

Comment by: RuuRd on

RuuRd Gravatarthanks 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 GravatarPHP 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: sachz on

sachz Gravatarthank you for this useful script (:

Comment by: Tomas on

Tomas GravatarThanks 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 Donat on

Jesse Donat GravatarIdeally 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 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 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 GravatarHey, 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~ GravatarMay 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 GravatarYou are right, I have corrected this in the latest release v0.1.5 and included a test specifically for that UA string.

Comment by: Oleksiy on

Oleksiy GravatarGreat job!
Best for today!

Comment by: Mark on

Mark GravatarMozilla/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 GravatarCode 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 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 GravatarI'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: Russell G. on

Russell G. GravatarAwesome! Made my day, thanks!

Comment by: Ueli on

Ueli GravatarThanks 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 GravatarHi, 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.

Email address will never be publicly visible.