代码之家  ›  专栏  ›  技术社区  ›  Gal

用php实现可靠的用户浏览器检测

  •  32
  • Gal  · 技术社区  · 16 年前

    get_browser 功能?你发现哪一个能带来更精确的结果?

    如果此方法是实用的,是否不建议将其用于输出相关的CSS链接,例如:

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

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

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

    Windows NT 6.0;SLCC1。净清除率 2.0.50727; Media Center PC 5.0。NET CLR 3.5.30729。净CLR 3.0.30618)

    Safari也给了一些奇怪的东西,里面还有“mozilla”。有什么好处?

    9 回复  |  直到 8 年前
        1
  •  21
  •   Veger    16 年前

    get_browser )可能比自己写东西要好,因为它有(更好的)支持,并且会用更新的版本更新。可能还有一些可用的库,用于以可靠的方式获取浏览器id。

    解码 $_SERVER['HTTP_USER_AGENT'] 这是很困难的,因为很多浏览器都有非常相似的数据,并且倾向于(错误地)使用这些数据来获取自己的利益。但是如果你真的想解码它们,你可以使用 this page 所有可用的代理ID。 此页还显示您的示例输出确实属于IE7 this page ,但正如我所说的,浏览器倾向于使用它为自己的利益,它可以在一个(稍微)其他格式。

        2
  •  69
  •   Ekramul Hoque    12 年前

    检查一下这个代码,我发现这个很有用。不检查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';
    
        3
  •  6
  •   Community Mohan Dere    8 年前

    用户代理可能是伪造的,最好不要依赖用户代理字符串,如果您只想检测方向,则可以使用CSS3媒体查询(您可以浏览著名的responsive framework bootstrap的CSS,检查如何使用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 */
        }    
    

    阅读更多: About CSS orientation detection

    或者可以使用JavaScript查找方向:

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

    阅读更多: About detect orientation using JS

    最后,如果您真的想使用用户代理字符串,那么这段代码将对您有很大帮助,几乎可以在每个浏览器上正常工作:

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

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

        4
  •  5
  •   Rob Hruska MegalomanINA    13 年前
    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(); 
    
        5
  •  3
  •   bobince    16 年前

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

    号码

    Vary 要包含的标题 User-Agent

    但如果你加上 Vary: User-Agent IE的坏缓存代码变得混乱,每次都重新加载页面。所以你赢不了。

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

        6
  •  2
  •   Community Mohan Dere    8 年前

    老帖子仍然出现在谷歌。get_browser()是最好的解决方案,但编辑php.ini可能是不可能的。根据 this post phpbrowscap 似乎完成了任务。文档不是很好,所以如果你不想它自动更新(默认值是开的),那么你需要设置

    $bc->updateMethod = phpbrowscap\Browscap::UPDATE_LOCAL;
    $bc->localFile = __DIR__ . "/php_browscap.ini";
    
        7
  •  2
  •   SwiftNinjaPro    6 年前

    (parentheses) 除IE外,IE的最后一个 . 我想知道是否只有在最后一次阅读之后 ) 可以提高准确性。

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

    Google Chrome

    Safari

    Firefox

    Edge

    IE (括号后未定义浏览器的例外情况)

    $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
    

    全功能:

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

    我也在chrome、edge和firefox开发人员上测试了这个功能,它工作得很准确(尽管我还没有测试这些浏览器的旧版本)

        8
  •  2
  •   phoenix    5 年前

    jenssegers/代理人

    浏览器/解析器

    我的职责是:

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

    使用方法如下:

    $browser = browser($userAgent);
    
    $browser->device();
    $browser->platform();
    $browser->browser();
    $browser->isMobile();
    $browser->isTablet();
    $browser->isDesktop();
    $browser->isRobot();
    
        9
  •  1
  •   scunliffe    16 年前

    我认为依赖userAgent有点弱,因为它经常是假的。

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

    或者如果你只想要一个IE6:

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

    因为它是一个被浏览器忽略的注释。。。除非IE在if测试与当前浏览器匹配时加载它。

        10
  •  0
  •   Jumper Pot    11 年前
    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>"; 
    
     ?>
    
        11
  •  0
  •   PrismaPixel Studios    8 年前

    Edge 在任何一个无人机上。

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

    然后,继续向后工作,因为早期版本的IE没有使用 Trident

    } 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" />';
    

    接下来我们需要以iOS浏览器为目标,这样后续的查询就不会干扰这个查询。所有iOS浏览器都使用webkit,但Opera Mini除外,它从远程服务器而不是设备进行渲染。这意味着我们可以用 iOS 排除包含 Opera .

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

    Gecko 在它的UA中,壁虎是它使用的引擎,因此我们可以瞄准它。通过使用 壁虎 ,我们可以识别在Gecko引擎(即SeaMonkey)上运行的所有浏览器。然而,许多浏览器使用这个术语 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" />';
    

    接下来,我们将确定Opera浏览器。歌剧院使用了 Presto 引擎到v12的末端。从v15开始,他们开始使用像Chrome一样的闪烁引擎。v12和更早版本在UA中包含了两个v15+没有的独特单词-- 歌剧院 急板地 . 你可以瞄准他们中的任何一个,因为他们总是在一起。对于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" />';
    

    接下来是狩猎。Safari使用AppleWebKit作为它的渲染引擎,但我们不能只针对它,因为Chrome也包括这两个引擎 AppleWebKit Safari 出于兼容性的原因。因此,我们需要寻找 AppleWebKit公司 而不是 Chrome

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

    最后,我们来看看Chrome。Chrome一直使用AppleWebKit直到v27。随着v28的发布,他们切换到闪烁引擎。我们可以针对两个引擎,但这将需要大量的代码。因为Chrome现在快到v70了,所以我们只需要搜索 因为几乎不可能有人还在运行Chrome的webkit版本。

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

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

    现在,我使用css文件引用供应商前缀来定位这里。请随意调整,因为需要有它做什么,你需要它做。我希望这有帮助。

    推荐文章