web-dev-qa-db-fra.com

détection fiable du navigateur de l'utilisateur avec php

Essayer de détecter le navigateur d'un utilisateur avec PHP uniquement, est-ce que $ _SERVER ['HTTP_USER_AGENT'] est un moyen fiable? Devrais-je plutôt choisir la fonction get_browser ? Lequel trouvez-vous apporte des résultats plus précis?

Si cette méthode est pragmatique, est-il déconseillé de l’utiliser pour générer des liens CSS pertinents, par exemple:

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

J'ai remarqué cette question , mais je voulais préciser si cela était bon pour la détection orientée CSS.

UPDATE: Quelque chose de très suspect: j'ai essayé echo $_SERVER['HTTP_USER_AGENT']; sur IE 7 et voici ce qu'il a généré:

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)

Safari a aussi donné quelque chose de bizarre avec "mozilla". Ce qui donne?

31
Gal

Utiliser une méthode existante (c.-à-d. get_browser ) est probablement préférable à écrire quelque chose vous-même, car elle supporte (mieux) et sera mise à jour avec les nouvelles versions. Il existe peut-être également des bibliothèques utilisables pour obtenir l’identifiant du navigateur de manière fiable.

Décoder le $_SERVER['HTTP_USER_AGENT'] est difficile, car beaucoup de navigateurs ont des données assez similaires et ont tendance à les (mal) utiliser à leur avantage. Mais si vous voulez vraiment les décoder, vous pouvez utiliser les informations sur cette page pour tous les identifiants d’agent disponibles. Cette page indique également que votre exemple de sortie appartient bien à IE 7. Vous trouverez plus d'informations sur les champs de l'identifiant de l'agent sur cette page , mais comme je l'ai déjà dit, l'utiliser pour leurs propres avantages et il pourrait être dans un (légèrement) autre format.

16
Veger

Vérifiez ce code, j'ai trouvé cela est utile. Ne vérifiez pas Mozilla Parce que la plupart des navigateurs l'utilisent comme chaîne d'agent utilisateur

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

si stripos ($ _ SERVER ['HTTP_USER_AGENT'], "mozilla")! == false)

Ce n'est pas un test utile, presque tous les navigateurs s'identifient comme Mozilla.

$ _SERVER ['HTTP_USER_AGENT'] est-il un moyen fiable?

Non.

Devrais-je plutôt opter pour la fonction get_browser?

Non.

La recherche de navigateur côté serveur est un jeu perdant. Mis à part tous les problèmes liés à l'analyse de la chaîne UA, aux navigateurs cachés, aux navigateurs obscurs et à la possibilité que l'en-tête n'existe pas, si vous renvoyez un contenu de page différent pour un autre navigateur, vous devez définir l'en-tête Vary à inclure User-Agent, sinon les mandataires en cache risquent de renvoyer la mauvaise version de la page au mauvais navigateur.

Mais si vous ajoutez Vary: User-Agent, le code de mise en cache cassé d'IE devient confus et recharge la page à chaque fois. Donc, vous ne pouvez pas gagner.

Si vous devez utiliser sniff-browser, vous devez le faire du côté client, en utilisant JavaScript et, en particulier dans le cas d'IE, les commentaires conditionnels. Heureusement, c'est IE qui prend en charge les commentaires conditionnels, car c'est le navigateur pour lequel vous avez souvent besoin de solutions de rechange. (Voir la réponse de scunliffe pour la stratégie la plus commune.)

3
bobince

L'agent utilisateur peut être falsifié et il est préférable de ne pas dépendre de la chaîne de l'agent utilisateur. Vous pouvez alors utiliser une requête multimédia CSS3 si vous voulez uniquement détecter partie d'orientation utilisant CSS)

Voici le petit 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 */
    }    

En savoir plus: À propos de la détection de l'orientation CSS

OU Vous pouvez trouver l'orientation en utilisant JavaScript:

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

En savoir plus: À propos de détecter l'orientation à l'aide de JS

Enfin, si vous voulez vraiment utiliser une chaîne d’agent d’utilisateur, alors ce code vous aidera beaucoup, fonctionne très bien sur presque tous les navigateurs:

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

Le code ci-dessus fonctionne pour moi presque sur tous les navigateurs et j'espère que cela vous aidera un peu.

2
Jay

Je pense que l’utilisation de userAgent est un peu faible, car elle peut (et est) souvent falsifiée.

Si vous voulez servir CSS uniquement pour IE, utilisez un commentaire conditionnel.

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

ou si vous voulez juste un pour IE6:

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

Depuis son commentaire, il est ignoré par les navigateurs ... sauf IE qui le charge si le test if correspond au navigateur actuel.

1
scunliffe

L'ancien post apparaît toujours dans Google. get_browser () est la meilleure solution mais éditer le fichier php.ini pourrait être impossible. Selon cet article vous ne pouvez pas ini_set la propriété browscap. Alors qu'est-ce qui reste? phpbrowscap semble faire son travail. Les docs ne sont pas géniaux, donc si vous ne voulez pas qu’elle se mette à jour automatiquement 

$bc->updateMethod = phpbrowscap\Browscap::UPDATE_LOCAL;
$bc->localFile = __DIR__ . "/php_browscap.ini";
1
Robert Labrie
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 était sur la bonne voie, mais sa réponse présente plusieurs défauts.

Tout d’abord, je commencerais par Edge car Internet Explorer ne contient pas le terme Edge dans aucun de ses agents utilisateurs.

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

Continuez ensuite à travailler en arrière, car les versions antérieures de IE n’utilisaient pas le moteur Trident et ne le contiendraient donc pas dans leur agent utilisateur.

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

Nous devons ensuite cibler les navigateurs iOS afin que les requêtes suivantes n'interfèrent pas avec celle-ci. Tous les navigateurs iOS utilisent webkit à l'exception d'Opera Mini, qui effectue le rendu à partir d'un serveur distant au lieu de l'appareil. Cela signifie que nous pouvons cibler le système d'exploitation dans l'agent utilisateur avec iOS et exclure les agents d'utilisateur qui contiennent Opera.

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

Ensuite, passez aux navigateurs Firefox. Bien que l’utilisation de Firefox comme terme de recherche fonctionne, elle n’identifie que les navigateurs Firefox - et non les navigateurs basés sur Firefox. Firefox contient Gecko dans son agent utilisateur, car Gecko est le moteur qu’il utilise et nous pouvons donc le cibler. En utilisant Gecko, nous pouvons identifier tous les navigateurs exécutés sur le moteur Gecko (SeaMonkey, par exemple). Cependant, de nombreux navigateurs utilisent le terme like Gecko pour des raisons de compatibilité. Nous devons donc nous assurer de faire correspondre Gecko et non 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" />';

Passons à autre chose, nous allons identifier les navigateurs Opera. Opera a utilisé le moteur Presto jusqu'à la fin de la v12. À partir de v15, ils ont commencé à utiliser le moteur Blink, comme Chrome. Les versions v12 et antérieures contenaient dans l'UA deux mots uniques que v15 + n'a pas --Opera et Presto. Vous pouvez cibler l'un ou l'autre, car ils étaient toujours présents ensemble. Pour la v15, Opera a commencé à utiliser OPR dans l'agent utilisateur.

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

La prochaine étape est Safari. Safari utilise AppleWebKit comme moteur de rendu, mais nous ne pouvons pas simplement le cibler, car Chrome inclut également AppleWebKit et Safari dans son agent utilisateur pour des raisons de compatibilité. Par conséquent, nous devons rechercher AppleWebKit et non Chrome.

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

Enfin, nous arrivons à Chrome. Chrome utilisait AppleWebKit jusqu'à la v27. Avec la version v28, ils sont passés au moteur Blink. Nous pourrions cibler les deux moteurs, mais cela demanderait beaucoup de code. Étant donné que Chrome est presque à la v70 maintenant, nous allons simplement rechercher Chrome car il est hautement improbable que quelqu'un exécute encore une version Webkit de Chrome.

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

Et le dernier mais non le moindre, votre solution de rechange.

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

Maintenant, j'ai utilisé des fichiers CSS faisant référence au préfixe du fournisseur à cibler ici. Ne hésitez pas à Tweak ce au besoin de l'avoir faire ce que vous avez besoin de faire. J'espère que cela a aidé.

0
Angeliss44