PHP detect browser name and version with phpbrowscap

This is an old problem: how to programatically detect the visitors browser and version. There are some very good reasons for wanting to do this:

  • Known compatibility issues
  • Customizing download or support links
  • Leveraging advanced features in newer browsers

Googling around for this, you always find the objection “someone can use a fake User-Agent string, so don’t bother”. That’s an obnoxious and unhelpful remark which should be deleted from forums. The vast majority of users do not adulterate their UA string, and those who do have to accept the broken experience that comes with it.

PHP has a native function called get_browser() which does the job. It relies on the php_browscap.ini file downloaded from the Browser Capabilities Project. To enable it you set a directive in the php.ini file and you’re off to the races. There is one catch: it can only be configured system wide. So what happens if you’re on shared hosting? Or if you want to keep your own version in git and not use the system version? The solution is phpbrowscap.

Before I get into browscap, there is one other thing tip I want to cover. What if you want this information client side? The Navigator.appName property appears promising, except that Mozilla, Chrome and Safari all return the exceptionally useless “Netscape” value. Only MSIE actually tells you who it is. You can use a server side snippet like this to expose the data client side:

echo "<script type=text/javascript>var Browser=" . json_encode($browser) . ";</script>\n";

This will work for you whether you got $browser from get_browser() or from phpbrowscap.

Phpbrowscap is fully compatible with get_browser() and is usually faster. It processes the browscap.ini file and writes it out to native PHP code so that subsequent loads don’t have to parse the ini. The simplest possible usage is:

require 'Browscap.php';
use phpbrowscap\Browscap;
$bc = new Browscap('/tmp');
$browser = $bc->getBrowser();

The default behaviour is to automatically download the latest version of the browscap.ini file and store it in the cache directory. If you have no access to write anywhere, and do not want auto-update, you need to do something like this:

$browscap = new phpbrowscap\Browscap(__DIR__);

For this to work, you must have a copy of browscap.ini and cache.php as generated by phpbrowscap. What I did was run the above version on some development box and copy the two files from /tmp to my source directory, then added them to my git.

The documentation isn’t great, so I’ll try to help out a little:

Directive Properties
doAutoUpdate true – default, also false
localFile Path to local copy of browscap. Used for offline updating.
updateMethod Browscap::UPDATE_LOCAL – use a local file specified in localFileBrowscap::UPDATE_FOPEN – Uses the fopen url wrapper (use file_get_contents)Browscap::UPDATE_FSOCKOPEN – Uses the socket functions (fsockopen)

Browscap::UPDATE_CURL – Uses the cURL extension

null or false – do not attempt update

cacheFilename Override the default cache file name of cache.php. Useful if auto-update is off.
iniFilename Override the default ini file name of browscap.ini. Useful if auto-update is off.

There are also some useful helper functions:

  • autodetectProxySettings() – gets settings from the *_proxy environment variables
  • addProxySettings($server, $port = 3128, $wrapper = ‘http’, $username = null, $password = null) – pretty obvious. If you’re wondering, 3128 is used by cntlm.
  • clearProxySettings() – I guess you might want this
  • updateCache() – Rebuild the cache file from ini

About robertlabrie
DevOps Engineer at The Network Inc in metro Atlanta. Too many interests to list here, check out my posts, or look me up on LinkedIn

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: