2010-02-13 64 views
27

试图仅使用PHP检测用户浏览器,$ _SERVER ['HTTP_USER_AGENT']是一种可靠的方式吗?我应该选择get_browser函数吗?你发现哪一个带来更精确的结果?使用php进行可靠的用户浏览器检测

如果此方法是务实的,是不明智的用它来输出相关的CSS的联系,例如:

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

我注意到this question,但是我想澄清这是否是良好的CSS-导向检测。

UPDATE: 东西真的怀疑:我的IE 7试过echo $_SERVER['HTTP_USER_AGENT'];,这就是它的输出:

的Mozilla/4.0(兼容; MSIE 7.0; 的Windows NT 6.0; SLCC1; .NET CLR 2.0.50727 ;媒体中心PC 5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30618)

Safari在这给了以 “Mozilla” 奇怪的事情了。是什么赋予了?

+0

的“Mozilla的/ 4.0”位在那里遗留原因......即使是在IE8。 – scunliffe 2010-02-13 13:30:47

+0

IE目前为Mozilla 4.0标识自己安静一段时间。我读过他们出于兼容性原因做了这些,但现在找不到源代码。如果我不得不猜测,我会说这是来自NetScape/IE时代的碎片。 – Bobby 2010-02-13 13:31:06

+0

*用户代理*不可靠。但这是唯一的猜测方式。 – Gumbo 2010-02-13 13:35:21

回答

15

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

$_SERVER['HTTP_USER_AGENT']进行解码很困难,因为很多浏览器都有非常相似的数据,并且倾向于(错误地)将它用于自己的好处。但是,如果您确实想解码它们,则可以使用this page上的所有可用代理ID的信息。 此页面还显示您的示例输出实际上属于IE 7.有关代理ID本身的字段的更多信息可以在this page找到,但正如我所说,浏览器倾向于将它用于自己的好处,它可能在(略)其他格式。

0

我认为依赖于userAgent是有点弱,因为它可以(而且)经常是伪造的。

如果您想要为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]--> 

,或者如果你只是想一个IE6:

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

自从评论通过浏览器其忽略......除了IE,如果如果测试的电流匹配的浏览器加载它。

+0

如果它是假的,谁在乎?它不像你依靠安全,它只是向用户显示一些东西... – 2015-06-18 15:47:22

2

如果stripos函数($ _ SERVER [ 'HTTP_USER_AGENT'], “Mozilla浏览器”)!== FALSE)

这不是一个有用的测试,几乎所有的浏览器自身标识为Mozilla的。

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

No.

我应该选择get_browser函数吗?

浏览器嗅探在服务器端是一个失败的游戏。除了试图解析UA字符串,浏览器的谎言,模糊的浏览器以及根本没有标题的可能性之外,如果您为其他浏览器返回不同的页面内容,则必须设置标头Vary包括User-Agent,否则高速缓存代理可能会将错误版本的页面返回给错误的浏览器。

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

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

6
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(); 
+4

说铬是Safari ... – 2012-12-17 17:48:21

+0

为什么你只用一种方法创建一个类?为什么不使用正常的功能呢? – 2014-12-05 20:15:58

+0

这是你的选择,只要你想。我正在举例说明如何检测浏览器。我从我的一个工作项目中拿走了。所有开发人员也更喜欢使用对象。 – user1524615 2014-12-08 08:05:06

53

检查此代码,我发现这很有用。不检查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'; 
+1

Awesome +1 this! – 2013-06-18 15:21:01

+4

不适用于IE 11(看看这里:http://www.nczonline.net/blog/2013/07/02/internet-explorer-11-dont-call-me-ie/) – 2013-12-19 10:12:50

+2

edited @rap -2-h – 2013-12-19 11:28:28

1

旧后仍然在谷歌出现。 get_browser()是最好的解决方案,但编辑php.ini可能是不可能的。根据this post你不能ini_set browscap属性。那剩下什么了? phpbrowscap似乎完成了工作。该文档是不是很大,所以如果你不希望它自动更新(默认为上),那么你需要设置

$bc->updateMethod = phpbrowscap\Browscap::UPDATE_LOCAL; 
$bc->localFile = __DIR__ . "/php_browscap.ini"; 
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>"; 

?> 
2

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

Here很少有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(); 

上面的代码工作对我来说几乎在每个浏览器上,我希望它能帮助你一点。

+1

哦,男孩,但你甚至不知道他想用这些信息做什么,并去建议媒体查询... – user151496 2015-06-23 12:27:12