2010-02-13 65 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