web-dev-qa-db-ja.com

phpによる信頼性の高いユーザーブラウザー検出

PHPのみ、$ _ SERVER ['HTTP_USER_AGENT']を使用してユーザーのブラウザを検出しようとしていますか?代わりに get_browser 関数を選択する必要がありますか?より正確な結果が得られると思いますか?

このメソッドが実用的である場合、適切なCSSリンクを出力するために使用することをお勧めしますか、例えば:

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

この質問 に気付きましたが、これがCSS指向の検出に適しているかどうかを明確にしたかったのです。

UPDATE:本当に疑わしい何か:echo $_SERVER['HTTP_USER_AGENT']; on IE 7そして、これはそれが出力するものです:

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は、「mozilla」でも奇妙なものを与えました。何が得られますか?

33
Gal

既存のメソッド(つまり get_browser )を使用することは、(より良い)サポートがあり、新しいバージョンで更新されるため、自分で何かを書くよりもおそらく良いでしょう。信頼できる方法でブラウザーIDを取得するために、使用可能なライブラリーもあるかもしれません。

$_SERVER['HTTP_USER_AGENT']のデコードは困難です。これは、多くのブラウザーが非常に類似したデータを持ち、自分の利益のためにそれを(誤って)使用する傾向があるためです。しかし、本当にデコードしたい場合は、利用可能なすべてのエージェントIDに このページ の情報を使用できます。このページは、出力例が実際にIE 7.に属していることも示しています。エージェントID自体のフィールドに関する詳細情報は このページ にありますが、すでにブラウザは自分の利益のためにそれを使用する傾向があり、(わずかに)他の形式である可能性があると述べました。

16
Veger

このコードを確認して、これが便利だとわかりました。ほとんどのブラウザはこれをユーザーエージェント文字列として使用するため、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';
59
Ekramul Hoque
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(); 
6
user1524615

if stripos($ _ SERVER ['HTTP_USER_AGENT']、 "mozilla")!== false)

これは有用なテストではありません。ほとんどすべてのブラウザは、Mozillaとして認識されます。

$ _SERVER ['HTTP_USER_AGENT']は信頼できる方法ですか?

番号。

代わりにget_browser関数を選択する必要がありますか?

番号。

サーバー側のブラウザスニッフィングは負けゲームです。 UA文字列、横たわるブラウザ、あいまいなブラウザ、ヘッダーがまったくない可能性を解析しようとするすべての問題は別として、異なるブラウザに異なるページコンテンツを返す場合は、Varyを含むヘッダーUser-Agent、それ以外の場合、キャッシュプロキシは間違ったバージョンのページを間違ったブラウザに返す可能性があります。

ただし、Vary: User-Agent IEの壊れたキャッシングコードは混乱し、ページを毎回リロードします。だからあなたは勝つことができません。

ブラウザでスニッフィングする必要がある場合は、JavaScriptを使用して、特にIEの場合は条件付きコメントを使用して、クライアント側に配置します。幸いなことに、IEは条件付きコメントをサポートします。これは回避策が必要なブラウザだからです。(最も一般的な戦略についてはscunliffeの回答を参照してください。)

3
bobince

ユーザーエージェントを偽装することができます。ユーザーエージェント文字列に依存しない方が、向きを検出する場合のみCSS3メディアクエリを使用できます(有名なレスポンシブフレームワーク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 */
    }    

続きを読む: CSS方向検出について

またはJavaScriptを使用して方向を見つけることができます:

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

詳細: 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();

上記のコードは、ほとんどすべてのブラウザーで機能します。少し役立つと思います。

3
Jay

古い投稿は引き続きGoogleに表示されます。 get_browser()が最善の解決策ですが、php.iniの編集は不可能かもしれません。 この投稿 によれば、browscapプロパティをini_setすることはできません。それで、何が残っていますか? phpbrowscap で仕事が完了したようです。ドキュメントは素晴らしいものではありませんので、自動更新したくない場合(デフォルトはオン)、設定する必要があります

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

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用に1つだけが必要な場合:

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

コメントはブラウザによって無視されるため... if =テストが現在のブラウザと一致する場合にロードするIEを除く.

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

 ?>
0
Jumper Pot

@Ekramul Hoqueは正しい軌道に乗っていたが、彼の答えにはいくつかの欠陥がある。

まず、Internet ExplorerのUAにはEdgeという用語が含まれていないため、Edgeから始めます。

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

その後、以前のバージョンの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" />';

次にiOSブラウザをターゲットにして、後続のクエリがこのブラウザに干渉しないようにする必要があります。すべてのiOSブラウザーは、デバイスではなくリモートサーバーからレンダリングを行うOpera Miniを除き、webkitを使用します。これは、iOSを使用してUAのOSをターゲットにし、Operaを含むUAを除外できることを意味します。

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

次に、Firefoxブラウザーに進みます。検索用語にFirefoxを使用しても機能しますが、Firefoxベースのブラウザーではなく、Firefoxブラウザーのみを識別します。 FirefoxのUAにはGeckoが含まれています。Geckoが使用するエンジンであるため、ターゲットにすることができます。 Geckoを使用することにより、Geckoエンジン(つまりSeaMonkey)で実行されるすべてのブラウザーを識別できます。ただし、多くのブラウザは互換性の理由でlike Geckoという用語を使用しているため、like Geckoではなく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ブラウザーを特定します。 Operaはv_12の終わりまでPrestoエンジンを使用していました。 v15から、ChromeのようなBlinkエンジンの使用を開始しました。 v12以前には、v15 +にはない2つの一意の単語がUAに含まれていました-OperaPresto。それらは常に一緒に存在していたため、どちらかをターゲットにできます。 v15では、OperaがUAでOPRの使用を開始しました。

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

最後に、Chromeにアクセスします。 Chromeはv27までAppleWebKitを使用していました。 v28リリースでは、Blinkエンジンに切り替えました。両方のエンジンをターゲットにできますが、多くのコードが必要になります。 Chromeがv70に近づいているので、ChromeのWebkitバージョンをまだ実行している人はほとんどいないので、Chromeを検索します。

} 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ファイルを使用して、ここでターゲットを設定します。必要に応じてこれを微調整して、必要な処理を実行してください。これがお役に立てば幸いです。

0
Angeliss44