使用 php 进行可靠的用户浏览器检测

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2257597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 05:45:12  来源:igfitidea点击:

reliable user browser detection with php

phpbrowser-detection

提问by Gal

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_browserfunction? which one do you find brings more precise results?

尝试仅使用 PHP 检测用户的浏览器,$_SERVER['HTTP_USER_AGENT'] 是否可靠?我应该选择get_browser函数吗?你觉得哪一个能带来更精确的结果?

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

如果这个方法是实用的,那么使用它来输出相关的 CSS 链接是否不明智,例如:

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.

我注意到了这个问题,但是我想澄清这是否有利于面向 CSS 的检测。

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

更新:真的很可疑:我echo $_SERVER['HTTP_USER_AGENT'];在 IE 7 上试过,这是它的输出:

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)

Mozilla/4.0(兼容;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?

Safari 也提供了一些奇怪的“mozilla”。是什么赋予了?

采纳答案by Veger

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.

使用现有的方法(即get_browser)可能比自己编写一些东西更好,因为它有(更好的)支持并且将更新为更新的版本。可能还有可用的库以可靠的方式获取浏览器 ID。

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 pagefor 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.

解码$_SERVER['HTTP_USER_AGENT']很困难,因为许多浏览器都有非常相似的数据,并且倾向于(误)使用它来为自己谋利。但是如果你真的想解码它们,你可以使用这个页面上的信息来获取所有可用的代理 ID。此页面还显示您的示例输出确实属于 IE 7。可以在此页面上找到有关代理 ID 本身字段的更多信息,但正如我所说,浏览器已经倾向于使用它来为自己谋利,并且它可能在(稍微)其他格式。

回答by Ekramul Hoque

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

检查此代码,我发现这很有用。不要检查 Mozilla,因为大多数浏览器使用它作为用户代理字符串

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';

回答by user1524615

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(); 

回答by Jay

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)

用户代理可以伪造,最好不要依赖用户代理字符串,如果您只想检测方向,则可以使用 CSS3 媒体查询(您可以探索著名的响应式框架引导程序的 CSS 以检查如何处理方向部分使用 CSS)

Here is little CSS :

这是小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

阅读更多:关于 CSS 方向检测

OR You can find the orientation using JavaScript :

或者您可以使用 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

阅读更多:关于使用 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.

上面的代码几乎适用于所有浏览器,我希望它对你有所帮助。

回答by bobince

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

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

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

这不是一个有用的测试,几乎每个浏览器都将自己标识为 Mozilla。

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

$_SERVER['HTTP_USER_AGENT'] 是一种可靠的方法吗?

No.

不。

Should I instead opt for the get_browser function?

我应该选择 get_browser 函数吗?

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 Varyheader to include User-Agent, otherwise caching proxies may return the wrong version of the page to the wrong browser.

服务器端的浏览器嗅探是一场失败的游戏。除了尝试解析 UA 字符串的所有问题、撒谎的浏览器、模糊的浏览器以及标题根本不存在的可能性之外,如果您为不同的浏览器返回不同的页面内容,您必须将Vary标题设置为include User-Agent,否则缓存代理可能会将错误版本的页面返回到错误的浏览器。

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

但是,如果您添加Vary: User-AgentIE 损坏的缓存代码,则会感到困惑并每次都重新加载页面。所以你赢不了。

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.)

如果您必须进行浏览器嗅探,那么可以在客户端使用 JavaScript,特别是在 IE 的情况下,使用条件注释。幸运的是 IE 支持条件注释,因为这是您经常需要解决方法的浏览器。(有关最常见的策略,请参阅 scunliffe 的回答。)

回答by Robert Labrie

Old post still comes up in Google. get_browser() is best solution but editing php.ini might be impossible. According to this postyou can't ini_set the browscap property. So what's left? phpbrowscapseems 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

旧帖子仍然出现在谷歌中。get_browser() 是最好的解决方案,但编辑 php.ini 可能是不可能的。根据这篇文章,您不能对 browscap 属性进行 ini_set。那么还剩下什么?phpbrowscap似乎完成了工作。文档不是很好,所以如果你不想让它自动更新(默认是打开的),那么你需要设置

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

回答by scunliffe

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

我认为依赖 userAgent 有点弱,因为它可以(并且)经常被伪造。

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

如果您只想为 IE 提供 CSS,请使用条件注释。

<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:

或者如果您只想要一个用于 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.

因为它是一个评论,它被浏览器忽略了......除非 IE 加载它,如果 if 测试与当前浏览器匹配。

回答by SwiftNinjaPro

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.

我注意到,真正的浏览器名称总是在最后一个之后(parentheses),IE 除外,在最后一个(parentheses). 我想知道只在最后一个之后阅读是否)可以提高准确性。

you may notice this in different user agents:

您可能会在不同的用户代理中注意到这一点:

Google Chrome

谷歌浏览器

Safari

苹果浏览器

Firefox

火狐

Edge

边缘

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

IE(括号后没有定义浏览器的例外)

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)

我还在 chrome、edge 和 firefox 开发人员上对此进行了测试,并且效果很好。(虽然我还没有测试过这些浏览器的旧版本)

回答by Jumper Pot

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>"; 

 ?>

回答by Angeliss44

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

@Ekramul Hoque 走在正确的轨道上,但他的回答有几个缺陷。

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

首先,我将从 Edge 开始,因为 Internet ExplorerEdge在其任何 UA中都不包含该术语。

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 Tridentengine and therefore won't contain it in their UA.

然后,继续向后工作,因为早期版本的 IE 没有使用Trident引擎,因此不会将它包含在他们的 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 iOSand exclude UAs that contain Opera.

接下来我们需要针对 iOS 浏览器,以便后续查询不会干扰这个浏览器。所有 iOS 浏览器都使用 webkit,但 Opera Mini 除外,它从远程服务器而不是设备进行渲染。这意味着我们可以将 UA 中的操作系统作为目标,iOS并排除包含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 Geckoin 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 Geckofor compatibility reasons, so we must be sure to match Geckoand not like Gecko.

接下来,转到 Firefox 浏览器。虽然使用 Firefox 作为搜索词可以工作,但它只能识别 Firefox 浏览器,而不是基于 Firefox 的浏览器。Firefox 包含Gecko在其 UA 中,因为 Gecko 是它使用的引擎,因此我们可以将其作为目标。通过使用Gecko,我们可以识别所有运行在 Gecko 引擎(即 SeaMonkey)上的浏览器。但是,许多浏览器like Gecko出于兼容性原因使用该术语,因此我们必须确保匹配Gecko而不是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 Prestoengine 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--Operaand Presto. You can target either of them as they were always present together. For v15, Opera began using OPRin the UA.

继续我们将识别 Opera 浏览器。Opera 使用该Presto引擎到 v12 结束。从 v15 开始,他们开始使用像 Chrome 一样的 Blink 引擎。v12 及更早版本在 UA 中包含两个独特的词,而 v15+ 没有--OperaPresto。您可以针对它们中的任何一个进行定位,因为它们总是一起出现。对于 v15,Opera 开始OPR在 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 AppleWebKitand Safariin its UA for compatibility reasons. Therefore, we need to search for AppleWebKitand not Chrome.

接下来是 Safari。Safari 使用 AppleWebKit 作为其渲染引擎,但我们不能仅仅以此为目标,因为出于兼容性原因,Chrome 还在其 UA 中包含AppleWebKitSafari。因此,我们需要搜索AppleWebKit而不是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 Chromeas it's highly unlikely anyone is still running a webkit version of Chrome.

最后,我们来到 Chrome。Chrome 在 v27 之前一直使用 AppleWebKit。在 v28 版本中,他们切换到 Blink 引擎。我们可以同时针对两个引擎,但这需要大量代码。由于 Chrome 现在几乎是 v70,我们将进行搜索,Chrome因为极不可能有人仍在运行 Chrome 的 webkit 版本。

} 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.

现在,我使用了引用供应商前缀的 css 文件来定位这里。随意根据需要调整它,让它做你需要做的事情。我希望这有帮助。