php user agent parser
Как получить User Agent в PHP. Как настроить browscap.ini
User Agent — это строка, которая характеризует программу, делающую запрос к веб-серверу. Пример такой строки:
Как можно увидеть, по User Agent можно определить операционную систему и версию веб-браузера.
По своей сути User Agent является одним из заголовков протокола HTTP. Причём этот заголовок присылает сам клиент. Отсюда очень важное следствие — строка User Agent может быть подменена на абсолютно любое значение или отсутствовать вовсе. В веб-браузерах это можно сделать с помощью плагинов.
Поэтому всегда помните о том, что Пользовательский Агент может быть спуфлен (заменён). Причём если вы, например, сохраняете полученные значения в базу данных, то помните о необходимости фильтрации данных, поскольку без должной фильтрации пользовательских данных это может стать причиной уязвимости SQL-инъекция.
Как настроить PHP для работы с get_browser
Ещё один способ — это использовать функцию get_browser. На самом деле, суть функции get_browser в том, чтобы показать возможности (поддерживаемые технологии) веб-браузера на основе User Agent. Причём необязательно для текущего пользователя — функция get_browser может в качество ввода принимать произвольную строку User Agent.
По умолчанию функция get_browser НЕ работает, поскольку требует дополнительной настройки в конфигурации PHP. Если не выполнить эту настройку, то при попытке использовать функцию get_browser вы будете получать примерно такое предупреждение:
Точнее говоря, требуется скачать специальный файл с перечнем свойств веб-браузера и указать путь до него в php.ini (главном конфигурационном файле PHP).
Эти файлы размещены на сайте http://browscap.org/. Всего для PHP имеется 3 варианта:
Итак, скачайте один из этих файлов — тот, который больше подходит под ваши нужды.
Для примера я скачал файл full_php_browscap.ini. Переименуйте скаченный файл в browscap.ini.
Переместите этот файл в директорию /etc/php/
Теперь откройте файл /etc/php/php.ini. Найдите там раздел:
Удалите вторую строку, а третью раскомментируйте и в качестве значения укажите абсолютный путь до файла, чтобы получилось так:
Чтобы изменения вступили в силу, перезапустите веб-сервер Apache.
На Debain, Ubuntu, Linux Mint, Kali Linux и их производных:
На Arch Linux, BlackArch и их производных:
Пример выполнения кода:
Обратите внимание, что в последних версиях PHP драмматически (в сотню раз) увеличена скорость работы функции get_browser.
Php user agent parser
User agent parsing is, was and will always be a painful thing.
The target of this package is to make it less painful, by providing an abstract layer for many user agent parsers.
Currently 11 local providers and 6 HTTP providers are available! See the comparison list here
The quality of this package is currently covered by
Using composer is currently the only supported way to install this package.
Note: to use local providers you need to install additional packages, which are listed inside the composer suggests section
You need to register an API key or install an additional package (listed in the section suggest of composer.json )
UserAgentParser comes with local and http providers
See detailed documenation here
Name | Type | Browser | Engine | Operating system | Device model | Device brand | Device type | Is mobile | Is bot | Bot name | Bot type | Comment |
---|---|---|---|---|---|---|---|---|---|---|---|---|
BrowscapFull | local | x | x | x | x | x | x | x | x | x | x | |
BrowscapLite | local | x | x | x | x | |||||||
BrowscapPhp | local | x | x | x | x | x | x | |||||
DonatjUAParser | local | x | ||||||||||
Endorphin | local | x | x | x | x | x | x | |||||
HandsetDetection | local | x | x | x | x | |||||||
JenssegersAgent | local | x | x | x | x | x | Based on MobileDetect | |||||
MatomoDeviceDetector | local | x | x | x | x | x | x | x | x | x | x | |
SinergiBrowserDetector | local | x | x | x | x | x | ||||||
UAParser | local | x | x | x | x | x | x | |||||
WhichBrowser | local | x | x | x | x | x | x | x | x | |||
Woothee | local | x | x | x | x | |||||||
Zsxsoft | local | x | x | x | x | |||||||
DeviceAtlasCom | http | x | x | x | x | free available | ||||||
FiftyOneDegreesCom | http | x | x | x | x | x | x | x | x | free unlimited | ||
NeutrinoApiCom | http | x | x | x | x | x | x | x | x | 25/day free | ||
UdgerCom | http | x | x | x | x | x | 500/month free (API key only for one month valid!) | |||||
UserAgentApiCom | http | x | x | x | x | x | 1000/day free | |||||
WhatIsMyBrowserCom | http | x | x | 500/month free |
Local providers are (most time) faster then HTTP providers and dont require a working internet connection. But you need to update them yourself from time to time, to make sure you detect the latest UAs
HTTP providers (API)
HTTP providers are simple to use, since you need only an API key to get started. But they require (always) a working internet connection.
Here is a comparison matrix, with many analyzed UserAgent strings, to help you device which provider fits your needs. Every provider has it’s strengh and weakness, so it will depend on your need, which one you should use.
This is very useful to improve your results. The chain provider starts with the first provider and checks if there is a result, if not it takes the next one and so on. If none of them have a result, it will throw a NoResultException like a single provider.
Php user agent parser
PHP User Agent Parser
A simple, streamlined PHP user-agent parser!
The new 1.* release does not break compatibility with 0.* and nothing need to change to upgrade. However, the global parse_user_agent is now deprecated; it has been replaced with the namespaced \donatj\UserAgent\parse_user_agent and functions exactly the same. You can easily replace any existing call to parse_user_agent with \donatj\UserAgent\parse_user_agent
In addition, 1.x adds a convenience object wrapper you may use should you prefer. More information on this is in the Usage section below.
You have your choice in user-agent parsers. This one detects all modern browsers in a very light, quick, understandable fashion. It is less than 200 lines of code, and consists of just three regular expressions! It can also correctly identify exotic versions of IE others fail on.
It offers 100% unit test coverage, is installable via Composer, and is very easy to use.
What It Does Not Do
This is not meant as a browser «knowledge engine» but rather a simple parser. Anything not adequately provided directly by the user agent string itself will simply not be provided by this.
User-agent strings are not a reliable source of OS Version!
I’m much more interested in keeping this thing tiny and accurate than adding niché features and would rather focus on things that can be done well.
All that said, there is the start of a branch to do it I created for a client if you want to poke it, I update it from time to time, but frankly if you need to reliably detect OS Version, using user-agent isn’t the way to do it. I’d go with JavaScript.
PHP User Agent is available through Packagist via Composer.
Install the latest version with:
The classic procedural use is as simple as:
The new object oriented wrapper form:
Currently Detected Platforms
Predefined helper constants from donatj\UserAgent\Platforms
Constant | Platform |
---|---|
Platforms::MACINTOSH | Macintosh |
Platforms::CHROME_OS | Chrome OS |
Platforms::LINUX | Linux |
Platforms::WINDOWS | Windows |
Platforms::ANDROID | Android |
Platforms::BLACKBERRY | BlackBerry |
Platforms::FREEBSD | FreeBSD |
Platforms::IPAD | iPad |
Platforms::IPHONE | iPhone |
Platforms::IPOD | iPod |
Platforms::KINDLE | Kindle |
Platforms::KINDLE_FIRE | Kindle Fire |
Platforms::NETBSD | NetBSD |
Platforms::NEW_NINTENDO_3DS | New Nintendo 3DS |
Platforms::NINTENDO_3DS | Nintendo 3DS |
Platforms::NINTENDO_DS | Nintendo DS |
Platforms::NINTENDO_SWITCH | Nintendo Switch |
Platforms::NINTENDO_WII | Nintendo Wii |
Platforms::NINTENDO_WIIU | Nintendo WiiU |
Platforms::OPENBSD | OpenBSD |
Platforms::PLAYBOOK | PlayBook |
Platforms::PLAYSTATION_3 | PlayStation 3 |
Platforms::PLAYSTATION_4 | PlayStation 4 |
Platforms::PLAYSTATION_5 | PlayStation 5 |
Platforms::PLAYSTATION_VITA | PlayStation Vita |
Platforms::SAILFISH | Sailfish |
Platforms::SYMBIAN | Symbian |
Platforms::TIZEN | Tizen |
Platforms::WINDOWS_PHONE | Windows Phone |
Platforms::XBOX | Xbox |
Platforms::XBOX_ONE | Xbox One |
Currently Detected Browsers
Predefined helper constants from donatj\UserAgent\Browsers
Constant | Browser |
---|---|
Browsers::ADSBOT_GOOGLE | AdsBot-Google |
Browsers::ANDROID_BROWSER | Android Browser |
Browsers::APPLEBOT | Applebot |
Browsers::BAIDUSPIDER | Baiduspider |
Browsers::BINGBOT | bingbot |
Browsers::BLACKBERRY_BROWSER | BlackBerry Browser |
Browsers::BROWSER | Browser |
Browsers::BUNJALLOO | Bunjalloo |
Browsers::CAMINO | Camino |
Browsers::CHROME | Chrome |
Browsers::CURL | curl |
Browsers::EDGE | Edge |
Browsers::FACEBOOKEXTERNALHIT | facebookexternalhit |
Browsers::FEEDVALIDATOR | FeedValidator |
Browsers::FIREFOX | Firefox |
Browsers::GOOGLEBOT | Googlebot |
Browsers::GOOGLEBOT_IMAGE | Googlebot-Image |
Browsers::GOOGLEBOT_VIDEO | Googlebot-Video |
Browsers::HEADLESSCHROME | HeadlessChrome |
Browsers::IEMOBILE | IEMobile |
Browsers::IMESSAGEBOT | iMessageBot |
Browsers::KINDLE | Kindle |
Browsers::LYNX | Lynx |
Browsers::MIDORI | Midori |
Browsers::MIUIBROWSER | MiuiBrowser |
Browsers::MSIE | MSIE |
Browsers::MSNBOT_MEDIA | msnbot-media |
Browsers::NETFRONT | NetFront |
Browsers::NINTENDOBROWSER | NintendoBrowser |
Browsers::OCULUSBROWSER | OculusBrowser |
Browsers::OPERA | Opera |
Browsers::PUFFIN | Puffin |
Browsers::SAFARI | Safari |
Browsers::SAILFISHBROWSER | SailfishBrowser |
Browsers::SAMSUNGBROWSER | SamsungBrowser |
Browsers::SILK | Silk |
Browsers::TELEGRAMBOT | TelegramBot |
Browsers::TIZENBROWSER | TizenBrowser |
Browsers::TWITTERBOT | Twitterbot |
Browsers::UC_BROWSER | UC Browser |
Browsers::VALVE_STEAM_TENFOOT | Valve Steam Tenfoot |
Browsers::VIVALDI | Vivaldi |
Browsers::WGET | Wget |
Browsers::WORDPRESS | WordPress |
Browsers::YANDEX | Yandex |
Browsers::YANDEXBOT | YandexBot |
More information is available at Donat Studios.
About
Lightning Fast, Minimalist PHP User Agent String Parser.
Php user agent parser
The PHP version of WhichBrowser for use on a server. Fully compatible with PHP 7.0 or higher, including PHP 8.
WhichBrowser/Parser-JavaScript
A JavaScript version of WhichBrowser for use with Node.js on the server
WhichBrowser/Server
A server written in PHP that provides a JavaScript API for use in the browser
But why almost completely useless and not completely useless? Well, there is always an exception to the rule. There are valid reasons to do browser sniffing: to improve the user experience or to gather intelligence about which browsers are used on your website. My website is html5test.com and I wanted to know which score belongs to which browser. And to do that you need a browser sniffing library.
Why is it extremely complicated?
Because everybody lies. Seriously, there is not a single browser that is completely truthful. Almost all browsers say they are Netscape 5 and almost all WebKit browsers say they are based on Gecko. Even Internet Explorer 11 now no longer claims to be IE at all, but instead an unnamed browser that is like Gecko. And it gets worse. That is why it is complicated.
What kind of information does it give? You get a nice object which has information about the browser, rendering engine, os and device. It gives you names and versions and even device manufacturer and model. And WhichBrowser is pretty tenacious. It gives you info that others don’t. For example:
Android is never mentioned
Despite the useragent header claiming to be a Series40 device, we know it’s actually running the Asha Platform and we also know that OviBrowser has been renamed to Nokia Xpress.
The useragent header looks like Opera 11.10 on Linux, but we know it’s Opera Mini. We can even figure out the real operating system and device model from other headers.
WhichBrowser requires with PHP 7.0 or higher and supports PHP 8. WhichBrowser is compatible with the PSR-4 autoloading standard and follows PSR-1 and PSR-2 coding style.
You can easily update WhichBrowser by running a simple command.
You should run this command as often as possible. You might even want to consider setting up a cron job for this purpose.
The first step require the Composer autoloader:
The second step is to create a new WhichBrowser\Parser object. This object will contain all the information the library could find about the browser. The object has a required parameter, either the headers send by the browser, or a useragent string. Using the headers is preferable, because it will allow a better detection, but if you have just the useragent string, this will also work.
First of all, you can call to toString() function to get a human readable identification:
Another possiblity is to query the object:
You can also access these properties directly:
Or access parts of these properties directly:
Finally you can also query versions directly:
It is possible to set additional options by passing an array as the second parameter when creating the Parser object.
Disabling detection of bots
In some cases you may want to disable the detection of bots. This allows the bot the deliberately fool WhichBrowser, so you can pick up the identity of useragent what the bot tries to mimic. This is especially handy when you want to use WhichBrowser to switch between different variants of your website and want to make sure crawlers see the right variant of the website. For example, a bot that mimics a mobile device will see the mobile variant of you site.
Enable result caching
WhichBrowser supports PSR-6 compatible cache adapters for caching results between requests. Using a cache is especially useful if you use WhichBrowser on every page of your website and a user visits multiple pages. During the first visit the headers will be parsed and the result will be cached. Upon further visits, the cached results will be used, which is much faster than having to parse the headers again and again.
There are adapters available for other types of caches, such as APC, Doctrine, Memcached, MongoDB, Redis and many more. The configuration of these adapters all differ from each other, but once configured, all you have to do is pass it as an option when creating the Parser object, or use the setCache() function to set it afterwards. WhichBrowser has been tested to work with the adapters provided by PHP Cache. For a list of other packages that provide adapters see Packagist.
For example, if you want to enable a memcached based cache you need to install an extra composer package:
And change the call to WhichBrowser/Parser as follows:
You can also specify after how many seconds a cached result should be discarded. The default value is 900 seconds or 15 minutes. If you think WhichBrowser uses too much memory for caching, you should lower this value. You can do this by setting the cacheExpires option or passing it as a second parameter to the setCache() function.
After a new WhichBrowser\Parser object is created, it contains a number of properties and functions. All of these properties are guaranteed to be present.
Properties:
Functions:
isType($type [,$type [,$type [,$type]]])
If a single argument is used, the function returns true if the argument matches the type propery of device object. The argument can optionally also provide a subtype by concatenating it to the type and seperating it with a semicolon. It can use multiple arguments in which case the function returns true if one of the arguments matches. If none of the arguments matches, it returns false
isDetected()
Is there actually some browser detected, or did we fail to detect anything?
toString()
Get a human readable representation of the detected browser, including operating system and device information.
The browser object
An object of the WhichBrowser\Model\Browser class is used for the browser property of the main WhichBrowser\Parser object and contains a number of properties. If a property is not applicable in this situation it will be null or undefined.
Properties:
Functions:
isFamily($name)
Does the family of this browser have this name, or does the browser itself have this name.
isUsing($name)
Is the browser using a webview using with the provided name.
getName()
Get the name of the browser
getVersion()
Get the version of the browser
toString()
Get a human readable representation of the detected browser
An object of the WhichBrowser\Model\Engine class is used for the engine property of the main WhichBrowser\Parser object and contains a number of properties. If a property is not applicable in this situation it will be null or undefined.
Properties:
Functions:
getName()
Get the name of the rendering engine
getVersion()
Get the version of the rendering engine
toString()
Get a human readable representation of the detected rendering engine
An object of the WhichBrowser\Model\Os class is used for the os property of the main WhichBrowser\Parser object and contains a number of properties. If a property is not applicable in this situation it will be null or undefined.
Properties:
Functions:
isFamily($name)
Does the family of this operating system have this name, or does the operating system itself have this name.
getName()
Get the name of the operating system
getVersion()
Get the version of the operating system
toString()
Get a human readable representation of the detected operating system
An object of the WhichBrowser\Model\Device class is used for the device property of the main WhichBrowser\Parser object and contains a number of properties. If a property is not applicable in this situation it will be null or undefined.
Properties:
The type property can contain any value from the following list:
If the type is «mobile», the subtype property can contain any value from the following list:
If the type is «gaming», the subtype property can contain any value from the following list:
Functions:
getManufacturer()
Get the name of the manufacturer
getModel()
Get the name of the model
toString()
Get a human readable representation of the detected device
An object of the WhichBrowser\Model\Family class is used for the family property of the WhichBrowser\Model\Browser and WhichBrowser\Model\Os object and contains a number of properties. If a property is not applicable in this situation it will be null or undefined.
Properties:
Functions:
getName()
Get the name of the family
getVersion()
Get the version of the family
toString()
Get a human readable representation of the family
An object of the WhichBrowser\Model\Using class is used for the using property of the WhichBrowser\Model\Browser object and contains a number of properties. If a property is not applicable in this situation it will be null or undefined.
Properties:
Functions:
getName()
Get the name of the webview
getVersion()
Get the version of the webview
toString()
Get a human readable representation of the webview
The version object
Properties:
Functions:
Php user agent parser
See changelog file for a list of changes.
Information about performance and scaling of UserAgentInfo.
UserAgentInfo uses other project to get the data it needs. See list of those projects.
PHP class for parsing user agent strings (HTTP_USER_AGENT). Includes mobile checks, bots and banned bots checks, browser types/versions and more. Based on browscap (via phpbrowscap), Mobile_Detect and ua-parser. Created for high traffic websites and fast batch processing.
This class doesn’t use any php.ini settings, so it can be deployed without changing server configuration.
please note:
It’s a new project and there are still some major things to do (see: todo list and the issues list).
Why another user agent detection class?
This project was crated because I couldn’t find one script that would give me all the information I needed from HTTP_USER_AGENT strings.
I was using browscap to identify bots, ban users, get information about browsers and user OS for internal monitoring, and some random scripts to detect and redirect mobile devices. In addition to that I had to add my own user agents to browscap detection because the project half died (it looks like it will be back on track soon though).
What’s the aim of this project?
Right now my goal is to update the project source parsers once a week. Updating more often is bad because this will reset the whole cache, so it’s not something you want to do every day. Perhaps the updates could be done just twice a month, but that may be too long to wait for new user agents identification.
Optionally: Remove get_browser() support from your server and turn off updates for browscap.ini files. You won’t have to use browscap via get_browser() any more.
Note: For best performance use fast caching system and opcache (bytecode cache).
UserAgentInfo is a class containing information about a single user agent string. It should provide means of identifying any data present in user agent string that can be used for practical purposes. Retrieve it by writing:
You can call those methods as many times as you want in your code, there is no need to cache the retrieved object, because it’s already cached by the main class.
The most important values you can get are:
note:
->isbanned used to be a part of browscap project, but it was removed. Right now the only source of ban information is a list of user agents I’ve added by hand. It’s not a very long list, but I’m working on adding the original list from browscap to the project too.
important note:
Performance and scaling
Test was run in two modes on data from example user agent strings (2506 unique entries).
The test was performed on Ubuntu virtual machine on a high end host machine.
You check all the user agents in one script (usually a cron script). It performs as follows:
This is a typical case of checking user agent information on a website (usually on apache or nginx server). It performs as follows:
So it’s slower than bulk parsing. However, you can go down to almost the same time if you use opcache (bytecode cache) on your server. It’s something you should have installed on your production server anyway, as it speed whole PHP by a lot.
Results with opcache on are:
As you can see, while the retrieval of information from the source parsers is quite fast, it’s still much slower than when getting cached data. This means that the logical way to go is to use the cache. If you also have opcache turned on (or are using bulk mode) you will be limited only by the speed and performance of your cache, without almost any overhead.
If you take that approach, you will be able use all information available from user agent strings at will and you won’t have to worry about performance problems. Even large bulk analysis of user agents won’t be an issue (for example, you can preform cron checks on IP+browser pairs to check for bots).
Of course, a question remains, what’s the cache hit ratio when you choose to use it for user agent string detection?
Test the cache hit ratio
My UserAgentInfo was running for about a week without any changes or cache resets on a set of websites with more than 1.5 million user visits per month. During that time:
That means that the number of calls that did not use cache was below 0.09% (one in 1000) which is a great result. Moreover, the most popular user agent strings were cached right away.
As you can imagine, the number of unique user agents does not grow proportionally to the website traffic. The number of popular browsers is quite limited, so the larger your website gets the lower chance of seeing a new user agent. This means that the more users you server the more difference using UserAgentInfo makes.
As long as you want to just check if a browser is mobile or not, or do some other one simple check based on user agent string, if you know what you’re doing, there is no need to use any advanced scripts.
However, UserAgentInfo delivers a very good average performance (limited by the performance of your cache system) while reliably providing as much information about the user as possible.
Switching to UserAgentInfo gives you many interesting opportunities you might have not thought about before.
By using UserAgentInfoPeer::getMy()->isBot() to completely disable session for all bots you can speed up your website and save a huge amount of disk operations. That’s because bots (in general) do not use cookies and thus PHP will, by default, create a new session for each bot call that is made to your website. So it’s entirely possible that more than 90% of your current sessions come from bot calls, and will never be used.
Relation to other projects
UserAgentInfo relies on multiple other projects to get its user agent information. Thanks to that it offers detection better than any other project that relies on its own parser, or only a single external parser.
The used projects are:
Some information is generated directly in UserAgentInfo. Currently those are two things:
About
PHP class for parsing user agent strings (HTTP_USER_AGENT). Includes mobile checks, bots and banned bots checks, browser types/versions and more. Based on browscap (via phpbrowscap), Mobile_Detect and ua-parser. Created for high traffic websites and fast batch processing.