41

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?

Community
  • 1
  • 1
Gal
  • 23,122
  • 32
  • 97
  • 118
  • The "Mozilla/4.0" bit is in there for legacy reasons... even in IE8. – scunliffe Feb 13 '10 at 13:30
  • IE identifies himself for quiet some time now as Mozilla 4.0. I've read that they did this for compatibility reasons, but can't find the source right now. If I'd have to guess, I'd say this is a debris from the NetScape/IE time. – Bobby Feb 13 '10 at 13:31
  • *User-Agent* is not reliable. But it’s the only way to guess. – Gumbo Feb 13 '10 at 13:35
  • 3
    @bobby http://webaim.org/blog/user-agent-string-history/ – Knu Feb 17 '10 at 00:51
  • Works with no problem on newest version of firefox. – user198989 May 16 '13 at 07:17
  • Where are many (good) browser detectors around. Try on of the listed here https://github.com/ThaDafinser/UserAgentParser – ThaDafinser Mar 31 '16 at 06:44

11 Answers11

72

Check this code , I've found this is useful. Don't check Mozilla because most browser use this as user agent string

if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE)
   echo 'Internet explorer';
 elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Trident') !== FALSE) //For Supporting IE 11
    echo 'Internet explorer';
 elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox') !== FALSE)
   echo 'Mozilla Firefox';
 elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome') !== FALSE)
   echo 'Google Chrome';
 elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mini') !== FALSE)
   echo "Opera Mini";
 elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') !== FALSE)
   echo "Opera";
 elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') !== FALSE)
   echo "Safari";
 else
   echo 'Something else';
Ekramul Hoque
  • 4,957
  • 3
  • 30
  • 31
  • 4
    Does not work for IE 11 (have a look here: http://www.nczonline.net/blog/2013/07/02/internet-explorer-11-dont-call-me-ie/ ) – rap-2-h Dec 19 '13 at 10:12
  • @Farhad Hi, I'm using this bit of code of yours, but I'm just curious if a switch statement wouldn't be faster. Personally it just feels like a switch statement would be the better fit. But thanks, that sorted my issue – Fernando Silva Jun 21 '14 at 16:46
  • not working, script shows return chrome in case of browser is opera. – The EasyLearn Academy Sep 02 '17 at 05:58
  • to check Edge browser you can add `elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Edge') !== FALSE) echo 'Microsoft Edge';` after `if` – Mohammad Salehi Dec 01 '18 at 15:53
  • This works really well, I have no idea why tho. Care to explain? –  Aug 21 '19 at 09:12
  • the updated method to detect Edge is `elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Edg') !== FALSE) echo 'Microsoft Edge';` for some reason they removed the `e` from the agent name. almost 8 years old and this method still works great – DrCustUmz Mar 08 '21 at 00:19
21

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
  • 37,240
  • 11
  • 105
  • 116
  • 1
    This function will not work on every server. Tried 3 servers - 0/3. – ViliusL Jun 18 '18 at 14:34
  • 2
    As ViliusL says, it won't work on every server because it requires the path to it's ini file to be set in the php.ini or the" http.config" file on Apache. This means you have to have access to it. – JSG Oct 16 '19 at 19:50
  • By the way, in case anyone has tried, setting the browscap directive at the script level using `ini_set('browscap', '/path/to/browscap.ini');` does not seem to work. This directive must be set in a php config file (as stated in the above comment). – Leo Galleguillos May 26 '20 at 18:46
  • it not work i am facing error "Warning: get_browser(): browscap ini directive not set in test.php on line 5" & i tried to find any solution but i see this post plz check https://stackoverflow.com/a/2036968/6353158 – Adeel Ahmed Baloch Jul 29 '22 at 05:39
7

User Agent can be faked and its better not to depend upon user agent string rather then you can use a CSS3 media queries if you only want to detect orientation (you can explore the CSS of the famous responsive framework bootstrap to check how you can handle the orientation part using CSS)

Here is little CSS :

    @media only screen and (max-width: 999px) {
     /* rules that only apply for canvases narrower than 1000px */
    }

    @media only screen and (device-width: 768px) and (orientation: landscape) {
    /* rules for iPad in landscape orientation */
    }

    @media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
    /* iPhone, Android rules here */
    }    

Read more : About CSS orientation detection

OR You can find the orientation using JavaScript :

    // Listen for orientation changes
    window.addEventListener("orientationchange", function() {
        // Announce the new orientation number
        alert(window.orientation);
    }, false);

Read more : About detect orientation using JS

Finally if you really wants to go with user agent string then this code will help you alot, work fine almost on every browser :

<?php
class BrowserDetection {

    private $_user_agent;
    private $_name;
    private $_version;
    private $_platform;

    private $_basic_browser = array (
       'Trident\/7.0' => 'Internet Explorer 11',
    'Beamrise' => 'Beamrise',
    'Opera' => 'Opera',
    'OPR' => 'Opera',
    'Shiira' => 'Shiira',
    'Chimera' => 'Chimera',
    'Phoenix' => 'Phoenix',
    'Firebird' => 'Firebird',
    'Camino' => 'Camino',
    'Netscape' => 'Netscape',
    'OmniWeb' => 'OmniWeb',
    'Konqueror' => 'Konqueror',
    'icab' => 'iCab',
     'Lynx' => 'Lynx',
    'Links' => 'Links',
    'hotjava' => 'HotJava',
    'amaya' => 'Amaya',
    'IBrowse' => 'IBrowse',
    'iTunes' => 'iTunes',
    'Silk' => 'Silk',
    'Dillo' => 'Dillo', 
    'Maxthon' => 'Maxthon',
    'Arora' => 'Arora',
    'Galeon' => 'Galeon',
    'Iceape' => 'Iceape',
    'Iceweasel' => 'Iceweasel',
    'Midori' => 'Midori',
    'QupZilla' => 'QupZilla',
    'Namoroka' => 'Namoroka',
    'NetSurf' => 'NetSurf',
    'BOLT' => 'BOLT',
    'EudoraWeb' => 'EudoraWeb',
    'shadowfox' => 'ShadowFox',
    'Swiftfox' => 'Swiftfox',
    'Uzbl' => 'Uzbl',
    'UCBrowser' => 'UCBrowser',
    'Kindle' => 'Kindle',
    'wOSBrowser' => 'wOSBrowser',
     'Epiphany' => 'Epiphany', 
    'SeaMonkey' => 'SeaMonkey',
    'Avant Browser' => 'Avant Browser',
    'Firefox' => 'Firefox',
    'Chrome' => 'Google Chrome',
    'MSIE' => 'Internet Explorer',
    'Internet Explorer' => 'Internet Explorer',
     'Safari' => 'Safari',
    'Mozilla' => 'Mozilla'  
    );

     private $_basic_platform = array(
        'windows' => 'Windows', 
     'iPad' => 'iPad', 
      'iPod' => 'iPod', 
    'iPhone' => 'iPhone', 
     'mac' => 'Apple', 
    'android' => 'Android', 
    'linux' => 'Linux',
    'Nokia' => 'Nokia',
     'BlackBerry' => 'BlackBerry',
    'FreeBSD' => 'FreeBSD',
     'OpenBSD' => 'OpenBSD',
    'NetBSD' => 'NetBSD',
     'UNIX' => 'UNIX',
    'DragonFly' => 'DragonFlyBSD',
    'OpenSolaris' => 'OpenSolaris',
    'SunOS' => 'SunOS', 
    'OS\/2' => 'OS/2',
    'BeOS' => 'BeOS',
    'win' => 'Windows',
    'Dillo' => 'Linux',
    'PalmOS' => 'PalmOS',
    'RebelMouse' => 'RebelMouse'   
     ); 

    function __construct($ua = '') {
        if(empty($ua)) {
           $this->_user_agent = (!empty($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:getenv('HTTP_USER_AGENT'));
        }
        else {
           $this->_user_agent = $ua;
        }
       }

    function detect() {
        $this->detectBrowser();
        $this->detectPlatform();
        return $this;
    }

    function detectBrowser() {
     foreach($this->_basic_browser as $pattern => $name) {
        if( preg_match("/".$pattern."/i",$this->_user_agent, $match)) {
            $this->_name = $name;
             // finally get the correct version number
            $known = array('Version', $pattern, 'other');
            $pattern_version = '#(?<browser>' . join('|', $known).')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
            if (!preg_match_all($pattern_version, $this->_user_agent, $matches)) {
                // we have no matching number just continue
            }
            // see how many we have
            $i = count($matches['browser']);
            if ($i != 1) {
                //we will have two since we are not using 'other' argument yet
                //see if version is before or after the name
                if (strripos($this->_user_agent,"Version") < strripos($this->_user_agent,$pattern)){
                    @$this->_version = $matches['version'][0];
                }
                else {
                    @$this->_version = $matches['version'][1];
                }
            }
            else {
                $this->_version = $matches['version'][0];
            }
            break;
        }
       }
   }

    function detectPlatform() {
      foreach($this->_basic_platform as $key => $platform) {
            if (stripos($this->_user_agent, $key) !== false) {
                $this->_platform = $platform;
                break;
            } 
      }
    }

   function getBrowser() {
      if(!empty($this->_name)) {
           return $this->_name;
      }
   }        

   function getVersion() {
       return $this->_version;
    }

    function getPlatform() {
       if(!empty($this->_platform)) {
          return $this->_platform;
       }
    }

    function getUserAgent() {
        return $this->_user_agent;
     }

     function getInfo() {
         return "<strong>Browser Name:</strong> {$this->getBrowser()}<br/>\n" .
        "<strong>Browser Version:</strong> {$this->getVersion()}<br/>\n" .
        "<strong>Browser User Agent String:</strong> {$this->getUserAgent()}<br/>\n" .
        "<strong>Platform:</strong> {$this->getPlatform()}<br/>";
     }
}  

$obj = new BrowserDetection();

echo $obj->detect()->getInfo();

The above code works for me almost on every browser and i hope it will help you a bit.

Community
  • 1
  • 1
Jay
  • 103
  • 2
  • 10
  • 2
    oh boy but you don't even know what he wants to do with that information and go suggesting media queries ... – user151496 Jun 23 '15 at 12:27
  • 1
    A small detail, in Edge it detects it as Chrome, to fix it just add in the _basic_browser array before Chrome the 'Edg' => 'Microsoft Edge', – ciberelfo Jan 25 '21 at 12:59
5
class Browser { 
    /** 
    Figure out what browser is used, its version and the platform it is 
    running on. 

    The following code was ported in part from JQuery v1.3.1 
    */ 
    public static function detect() { 
        $userAgent = strtolower($_SERVER['HTTP_USER_AGENT']); 

        // Identify the browser. Check Opera and Safari first in case of spoof. Let Google Chrome be identified as Safari. 
        if (preg_match('/opera/', $userAgent)) { 
            $name = 'opera'; 
        } 
        elseif (preg_match('/webkit/', $userAgent)) { 
            $name = 'safari'; 
        } 
        elseif (preg_match('/msie/', $userAgent)) { 
            $name = 'msie'; 
        } 
        elseif (preg_match('/mozilla/', $userAgent) && !preg_match('/compatible/', $userAgent)) { 
            $name = 'mozilla'; 
        } 
        else { 
            $name = 'unrecognized'; 
        } 

        // What version? 
        if (preg_match('/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/', $userAgent, $matches)) { 
            $version = $matches[1]; 
        } 
        else { 
            $version = 'unknown'; 
        } 

        // Running on what platform? 
        if (preg_match('/linux/', $userAgent)) { 
            $platform = 'linux'; 
        } 
        elseif (preg_match('/macintosh|mac os x/', $userAgent)) { 
            $platform = 'mac'; 
        } 
        elseif (preg_match('/windows|win32/', $userAgent)) { 
            $platform = 'windows'; 
        } 
        else { 
            $platform = 'unrecognized'; 
        } 

        return array( 
            'name'      => $name, 
            'version'   => $version, 
            'platform'  => $platform, 
            'userAgent' => $userAgent 
        ); 
    } 
} 


$browser = Browser::detect(); 
Rob Hruska
  • 118,520
  • 32
  • 167
  • 192
LifeInstructor
  • 1,622
  • 1
  • 20
  • 24
  • 1
    why are you creating a class with only one method in it? why not using a normal function instead? – Michael Walter Dec 05 '14 at 20:15
  • That is your choice do as you want.I am giving an example how to detect the browser. I have taken from one of my working projects. Also using objects is more preferable for all developers. – LifeInstructor Dec 08 '14 at 08:05
  • This worked for me, to fix the safari/chrome issue: if ( stripos($userAgent, 'Firefox') !== false ) { $name = 'firefox'; } elseif ( stripos($userAgent, 'MSIE') !== false ) { $name = 'ie'; } elseif ( stripos($userAgent, 'Trident') !== false ) { $name = 'ie'; } elseif ( stripos($userAgent, 'Chrome') !== false ) { $name = 'chrome'; } elseif ( stripos($userAgent, 'Safari') !== false ) { $name = 'safari'; } – Gerardo Jaramillo Aug 30 '16 at 00:40
4

Something I notice, the real browser name always comes after the last (parentheses) with the exception of IE, where there is no browser name after the last (parentheses). I wonder if only reading after the last ) could improve accuracy.

you may notice this in different user agents:

Google Chrome

Safari

Firefox

Edge

IE (the exception where no browser is defined after parentheses)

example:

$userBrowser = (!empty($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:getenv('HTTP_USER_AGENT'));
$userBrowser = explode(')', $userBrowser);
$userBrowser = $userBrowser[count($userBrowser)-1];

echo $userBrowser; //this has many inaccurate browsers stripped out

A full function:

function getUserBrowser(){
  $fullUserBrowser = (!empty($_SERVER['HTTP_USER_AGENT'])? 
  $_SERVER['HTTP_USER_AGENT']:getenv('HTTP_USER_AGENT'));
  $userBrowser = explode(')', $fullUserBrowser);
  $userBrowser = $userBrowser[count($userBrowser)-1];

  if((!$userBrowser || $userBrowser === '' || $userBrowser === ' ' || strpos($userBrowser, 'like Gecko') === 1) && strpos($fullUserBrowser, 'Windows') !== false){
    return 'Internet-Explorer';
  }else if((strpos($userBrowser, 'Edge/') !== false || strpos($userBrowser, 'Edg/') !== false) && strpos($fullUserBrowser, 'Windows') !== false){
    return 'Microsoft-Edge';
  }else if(strpos($userBrowser, 'Chrome/') === 1 || strpos($userBrowser, 'CriOS/') === 1){
    return 'Google-Chrome';
  }else if(strpos($userBrowser, 'Firefox/') !== false || strpos($userBrowser, 'FxiOS/') !== false){
    return 'Mozilla-Firefox';
  }else if(strpos($userBrowser, 'Safari/') !== false && strpos($fullUserBrowser, 'Mac') !== false){
    return 'Safari';
  }else if(strpos($userBrowser, 'OPR/') !== false && strpos($fullUserBrowser, 'Opera Mini') !== false){
    return 'Opera-Mini';
  }else if(strpos($userBrowser, 'OPR/') !== false){
    return 'Opera';
  }
  return false;
}

echo 'browser detect: '.getUserBrowser();

I also tested this on chrome, edge, and firefox developer, and it worked accurately. (although I have not tested older versions of these browsers yet)

SwiftNinjaPro
  • 787
  • 8
  • 17
4

Most PHP packages that I've found seemed to be pretty good but I couldn't find a good one that gave me everything I needed so I built a Laravel helper to combine 3 of them.

Here are the packages:

jenssegers/agent

whichbrowser/parser

cbschuld/browser.php

And here's my function:

function browser($userAgent)
{
    $agent = new \Jenssegers\Agent\Agent();
    $agent->setUserAgent($userAgent);

    $result = new \WhichBrowser\Parser($userAgent);

    $browser = new \Browser($userAgent);

    return new class($agent, $result, $browser)
    {
        public function __construct($agent, $result, $browser)
        {
            $this->agent = $agent;
            $this->result = $result;
            $this->browser = $browser;
        }
        public function device()
        {
            return $this->agent->device() ?: $this->result->device->toString() ?: $this->browser->getPlatform();
        }
        public function browser()
        {
            return $this->agent->browser() ?: $this->result->browser->name ?: $this->browser->getBrowser();
        }
        public function platform()
        {
            return $this->agent->platform() ?: $this->result->os->name ?: $this->browser->getPlatform();
        }
        public function isMobile()
        {
            return $this->agent->isPhone() ?: $this->result->isType('mobile') ?: $this->browser->isMobile();
        }
        public function isTablet()
        {
            return $this->result->isType('tablet') ?: $this->browser->isTablet();
        }
        public function isDesktop()
        {
            return $this->agent->isDesktop() ?: $this->result->isType('desktop') ?: (! $this->browser->isMobile() && ! $this->browser->isTablet());
        }
        public function isRobot()
        {
            return $this->agent->isRobot() ?: $this->browser->isRobot();
        }
    };

Here's how to use it:

$browser = browser($userAgent);

$browser->device();
$browser->platform();
$browser->browser();
$browser->isMobile();
$browser->isTablet();
$browser->isDesktop();
$browser->isRobot();
phoenix
  • 1,629
  • 20
  • 11
3

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
  • 528,062
  • 107
  • 651
  • 834
2

Old post still comes up in Google. get_browser() is best solution but editing php.ini might be impossible. According to this post you can't ini_set the browscap property. So what's left? phpbrowscap seems to get the job done. The docs aren't great so if you don't want it to auto-update (the default is on), then you need to set

$bc->updateMethod = phpbrowscap\Browscap::UPDATE_LOCAL;
$bc->localFile = __DIR__ . "/php_browscap.ini";
Community
  • 1
  • 1
1

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
  • 62,582
  • 25
  • 126
  • 161
  • If it's faked, who cares? It's not like you are relying security on it, it's just about displaying something to the user… – o0'. Jun 18 '15 at 15:47
0
Check This Code :      
   <?php     

class OS_BR{    
private $agent = "";
private $info = array();

function __construct(){
    $this->agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : NULL;
    $this->getBrowser();
    $this->getOS();
}     
function getBrowser(){     
    $browser = array("Navigator"            => "/Navigator(.*)/i",
                     "Firefox"              => "/Firefox(.*)/i",
                     "Internet Explorer"    => "/MSIE(.*)/i",
                     "Google Chrome"        => "/chrome(.*)/i",
                     "MAXTHON"              => "/MAXTHON(.*)/i",
                     "Opera"                => "/Opera(.*)/i",
                     );
    foreach($browser as $key => $value){
        if(preg_match($value, $this->agent)){
            $this->info = array_merge($this->info,array("Browser" => $key));
            $this->info = array_merge($this->info,array(
              "Version" => $this->getVersion($key, $value, $this->agent)));
            break;
        }else{
            $this->info = array_merge($this->info,array("Browser" => "UnKnown"));
            $this->info = array_merge($this->info,array("Version" => "UnKnown"));
        }
    }
    return $this->info['Browser'];
}
function getOS(){
    $OS = array("Windows"   =>   "/Windows/i",
                "Linux"     =>   "/Linux/i",
                "Unix"      =>   "/Unix/i",
                "Mac"       =>   "/Mac/i"
                );

    foreach($OS as $key => $value){
        if(preg_match($value, $this->agent)){
            $this->info = array_merge($this->info,array("Operating System" => $key));
            break;
        }
    }
    return $this->info['Operating System'];
}

function getVersion($browser, $search, $string){
    $browser = $this->info['Browser'];
    $version = "";
    $browser = strtolower($browser);
    preg_match_all($search,$string,$match);
    switch($browser){
        case "firefox": $version = str_replace("/","",$match[1][0]);
        break;

        case "internet explorer": $version = substr($match[1][0],0,4);
        break;

        case "opera": $version = str_replace("/","",substr($match[1][0],0,5));
        break;

        case "navigator": $version = substr($match[1][0],1,7);
        break;

        case "maxthon": $version = str_replace(")","",$match[1][0]);
        break;

        case "google chrome": $version = substr($match[1][0],1,10);
    }
    return $version;
}

function showInfo($switch){
    $switch = strtolower($switch);
    switch($switch){
        case "browser": return $this->info['Browser'];
        break;

        case "os": return $this->info['Operating System'];
        break;

        case "version": return $this->info['Version'];
        break;

        case "all" : return array($this->info["Version"], 
          $this->info['Operating System'], $this->info['Browser']);
        break;

        default: return "Unkonw";
        break;

    }
}
 }    


$obj = new OS_BR();

echo $obj->showInfo('browser');

echo $obj->showInfo('version');

echo $obj->showInfo('os');

echo "<pre>".print_r($obj->showInfo("all"),true)."</pre>"; 

 ?>
Jasper
  • 363
  • 5
  • 10
0

@Ekramul Hoque was on the right track but there are several flaws to his answer.

First of all, I would begin with Edge as Internet Explorer does not contain the term Edge in any of its UAs.

if(strpos($_SERVER['HTTP_USER_AGENT'], 'Edge') !== FALSE) {
  echo '<link type="text/css" href="ms.css" />';

Then, continue to work backward as earlier versions of IE didn't use the Trident engine and therefore won't contain it in their UA.

} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Trident') !== FALSE) {
  echo '<link type="text/css" href="ms.css" />';
} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE) {
  echo '<link type="text/css" href="ms.css" />';

We need to target iOS browsers next so that the subsequent queries don't interfere with this one. All iOS browsers use webkit with the exception of Opera Mini, which does its rendering from a remote server instead of the device. This means that we can target the OS in the UA with iOS and exclude UAs that contain Opera.

} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'iOS') && !strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') !== FALSE {
  echo '<link type="text/css" href="webkit.css" />';

Next, move on to Firefox browsers. While using Firefox for the search term will work, it will only identify Firefox browsers--not Firefox based browsers. Firefox contains Gecko in its UA as Gecko is the engine that it uses, and we can therefore target that. By using Gecko, we can identify all browsers that run on the Gecko engine (ie SeaMonkey). However, many browsers use the term like Gecko for compatibility reasons, so we must be sure to match Gecko and not like Gecko.

} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Gecko') && !strpos($_SERVER['HTTP_USER_AGENT'], 'like Gecko') !== FALSE) {
  echo '<link type="text/css" href="moz.css" />';

Moving on we'll identify Opera browsers. Opera used the Presto engine to the end of v12. Starting with v15, they began using the Blink engine like Chrome. v12 and earlier contained two unique words in the UA that v15+ doesn't have--Opera and Presto. You can target either of them as they were always present together. For v15, Opera began using OPR in the UA.

} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Presto') !== FALSE) {
  echo '<link type="text/css" href="o.css" />';
} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'OPR') !== FALSE) {
  echo '<link type="text/css" href="normal.css" />';

Next up is Safari. Safari uses AppleWebKit as its rendering engine, but we can't just target that because Chrome also includes both AppleWebKit and Safari in its UA for compatibility reasons. Therefore, we need to search for AppleWebKit and not Chrome.

} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'AppleWebKit') && !strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome') !== FALSE) {
  echo '<link type="text/css" href="webkit.css" />';

Finally, we get to Chrome. Chrome used AppleWebKit until v27. With the v28 release, they switched over to the Blink engine. We could target both engines but it would require a lot of code. Being that Chrome is almost to v70 now, we'll just search for Chrome as it's highly unlikely anyone is still running a webkit version of Chrome.

} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome') !== FALSE {
  echo '<link type="text/css" href="normal.css" />';

And last but not least, your fallback/else.

} else {
  echo '<link type="text/css" href="normal.css" />';
}

Now, I used css files referring to the vendor prefix to target here. Feel free to tweak this as needed to have it do what you need it to do. I hope this helped.

Angeliss44
  • 125
  • 1
  • 3
  • 20