views:

360

answers:

3

Trying to detect a user's browser with PHP only, is $_SERVER['HTTP_USER_AGENT'] a reliable way? Should I instead opt for the get_browser function? which one do you find brings more precise results?

If this method is pragmatic, is it ill advised to use it for outputting pertinent CSS links, for example:

if(stripos($_SERVER['HTTP_USER_AGENT'],"mozilla")!==false)
   echo '<link type="text/css" href="mozilla.css" />';

I noticed this question, however I wanted to clarify whether this is good for CSS-oriented detection.

UPDATE: something really suspicious: I tried echo $_SERVER['HTTP_USER_AGENT']; on IE 7 and this is what it output:

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30618)

Safari gave something weird with "mozilla" in it too. What gives?

+2  A: 

Using an existing method (ie get_browser) is probably better than writing something yourself, since it has (better) support and will be updated with newer versions. There might be also usable libraries out there for getting the browser id in a reliable way.

Decoding the $_SERVER['HTTP_USER_AGENT'] is difficult, since a lot of browsers have quite similar data and tend to (mis)use it for their own benefits. But if you really want to decode them, you could use the information on this page for all available agent ids. This page also shows that your example output indeed belongs to IE 7. More information about the fields in the agent id itself can be found on this page, but as I said already browsers tend to use it for their own benefits and it could be in a (slightly) other format.

Veger
+2  A: 

I think relying on the userAgent is a bit weak as it can (and is) often faked.

If you want to serve up CSS just for IE, use a conditional comment.

<link type="text/css" rel="stylesheet" href="styles.css"/><!--for all-->
<!--[if IE]>
  <link type="text/css" rel="stylesheet" href="ie_styles.css"/>
<![endif]-->

or if you just want one for IE6:

<!--[if IE 6]>
  <link type="text/css" rel="stylesheet" href="ie6_styles.css"/>
<![endif]-->

Since its a comment its ignored by browsers... except IE that loads it if the if test matches the current browser.

scunliffe
A: 

if stripos($_SERVER['HTTP_USER_AGENT'],"mozilla")!==false)

That's not a useful test, almost every browser identifies itself as Mozilla.

is $_SERVER['HTTP_USER_AGENT'] a reliable way?

No.

Should I instead opt for the get_browser function?

No.

Browser-sniffing on the server side is a losing game. Apart from all the issues of trying to parse the UA string, the browsers that lie, the obscure browsers, and the possibility the header isn't there at all, if you return different page content for a different browser you must set the Vary header to include User-Agent, otherwise caching proxies may return the wrong version of the page to the wrong browser.

But if you add Vary: User-Agent IE's broken caching code gets confused and reloads the page every time. So you can't win.

If you must browser-sniff, the place to do it is on the client side, using JavaScript and, specifically in IE's case, conditional comments. It's lucky that it's IE that supports conditional comments, since that's the one browser you often need workarounds for. (See scunliffe's answer for the most common strategy.)

bobince