PHP:具有Version / x.x.x的浏览器版本号user-agent(Safari& Opera)

时间:2013-09-15 23:02:13

标签: php regex version user-agent pcre

我编写了一个简单的类来检查用户代理是否为不兼容的浏览器显示警告。我正在做这个服务器端,我知道它可能是客户端。

首先关闭,我对写正则表达不太好..

我编写了一个正则表达式,用于搜索小写浏览器名称,后跟版本号。 我使用 这样的数组foreach()执行此操作:

<?php
    $browsers = Array('msie','chrome','safari','firefox','opera');    

    foreach($browsers as $i => $browser)  
    {
        $regex = "#({$browser})[/ ]([0-9.]*)#i";

        if(preg_match($regex, $useragent, $matches))
        {
            echo "Browser: \"{$matches[0]}\", version: \"{$matches[1]}\"";
        }
    }
?>

这会产生:Browser: "Firefox", version "23.0.6"

我发现这适用于Firefox,MS IE和旧版本的Opera。但是,某些浏览器(如Safari和较新版本的Opera)具有不同的用户代理字符串,其中包含Version / x.x.x,即

只是为了给你一个想法,这里有3个用户代理字符串,我需要突出显示。

  1. Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1
  2. Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)
  3. Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14
  4. 所以在以下每个人的逻辑中都是正确的:

    • 如果字符串中有Version/x.x.x,则为版本号。
    • 如果没有,则Browsername/x.x.x是版本号。

    此外,如果您查看上面的第一个和最后一个用户代理字符串,您可以在浏览器名称后面看到Version可以在 之前。

    有人可以帮我制作一个与preg_match()一起使用的正则表达式吗?我是否需要使用条件语句或是否可以搜索可选分组?我有点困惑..

    谢谢!

    编辑17-09-2013:我忘了提及,我不想使用 get_browser() ,它使用一个巨大的库来检测浏览器功能等我只需要一个简短的“白名单”浏览器,这需要几毫秒而不是几百毫秒才能读取浏览cap.ini文件。否则乔治的回答将是 回答..

4 个答案:

答案 0 :(得分:6)

鉴于您的一些结果,这是有效的。它可能并非在所有情况下,但它会大大减少您的处理时间。

我使用单个正则表达式来提取版本:

(?:version\/|(?:msie|chrome|safari|firefox|opera) )([\d.]+)

然后,由于您只搜索一些完全字符串,您可以使用php的stripos()来检查浏览器字符串。

<?php
$useragent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1";
$browsers = Array('msie','chrome','safari','firefox','opera');
preg_match("/(?:version\/|(?:msie|chrome|safari|firefox|opera) )([\d.]+)/i", $useragent, $matches);
$version = $matches[1];
$browser = "";
foreach($browsers as $b)  
{
    if (stripos($useragent, $b) !== false)
    {
        $browser = ucfirst($b);
        break;
    }
}
echo "$browser: $version";
?>

这样做的好处是立竿见影的:

  • 您不需要使用正则表达式多次测试useragent。
  • stripos()处理速度明显快于正则表达式。

你也可以在这里使用正则表达式:http://regex101.com/r/lE6lI2

答案 1 :(得分:6)

由于我在某些浏览器上遇到Remus的回答时遇到了一些问题,所以结束的方式有所不同。

<?php

function get_useragent_info($ua)
{
    $ua = is_null($ua) ? $_SERVER['HTTP_USER_AGENT'] : $ua;
    // Enumerate all common platforms, this is usually placed in braces (order is important! First come first serve..)
    $platforms = "Windows|iPad|iPhone|Macintosh|Android|BlackBerry";

    // All browsers except MSIE/Trident and.. 
    // NOT for browsers that use this syntax: Version/0.xx Browsername  
    $browsers = "Firefox|Chrome"; 

    // Specifically for browsers that use this syntax: Version/0.xx Browername  
    $browsers_v = "Safari|Mobile"; // Mobile is mentioned in Android and BlackBerry UA's

    // Fill in your most common engines..
    $engines = "Gecko|Trident|Webkit|Presto";

    // Regex the crap out of the user agent, making multiple selections and.. 
    $regex_pat = "/((Mozilla)\/[\d\.]+|(Opera)\/[\d\.]+)\s\(.*?((MSIE)\s([\d\.]+).*?(Windows)|({$platforms})).*?\s.*?({$engines})[\/\s]+[\d\.]+(\;\srv\:([\d\.]+)|.*?).*?(Version[\/\s]([\d\.]+)(.*?({$browsers_v})|$)|(({$browsers})[\/\s]+([\d\.]+))|$).*/i";

    // .. placing them in this order, delimited by |
    $replace_pat = '$7$8|$2$3|$9|${17}${15}$5$3|${18}${13}$6${11}';

    // Run the preg_replace .. and explode on |
    $ua_array = explode("|",preg_replace($regex_pat, $replace_pat, $ua, PREG_PATTERN_ORDER));

    if (count($ua_array)>1)
    {
        $return['platform']  = $ua_array[0];  // Windows / iPad / MacOS / BlackBerry
        $return['type']      = $ua_array[1];  // Mozilla / Opera etc.
        $return['renderer']  = $ua_array[2];  // WebKit / Presto / Trident / Gecko etc.
        $return['browser']   = $ua_array[3];  // Chrome / Safari / MSIE / Firefox

        /* 
           Not necessary but this will filter out Chromes ridiculously long version
           numbers 31.0.1234.122 becomes 31.0, while a "normal" 3 digit version number 
           like 10.2.1 would stay 10.2.1, 11.0 stays 11.0. Non-match stays what it is.
        */

        if (preg_match("/^[\d]+\.[\d]+(?:\.[\d]{0,2}$)?/",$ua_array[4],$matches))
        {
            $return['version'] = $matches[0];     
        }
        else
        {
            $return['version'] = $ua_array[4];
        }
    }
    else
    {
        /*
           Unknown browser.. 
           This could be a deal breaker for you but I use this to actually keep old
           browsers out of my application, users are told to download a compatible
           browser (99% of modern browsers are compatible. You can also ignore my error
           but then there is no guarantee that the application will work and thus
           no need to report debugging data.
         */

        return false;
    }

    // Replace some browsernames e.g. MSIE -> Internet Explorer
    switch(strtolower($return['browser']))
    {
        case "msie":
        case "trident":
            $return['browser'] = "Internet Explorer";
            break;
        case "": // IE 11 is a steamy turd (thanks Microsoft...)
            if (strtolower($return['renderer']) == "trident")
            {
                $return['browser'] = "Internet Explorer";
            }
        break;
    }

    switch(strtolower($return['platform']))
    {
        case "android":    // These browsers claim to be Safari but are BB Mobile 
        case "blackberry": // and Android Mobile
            if ($return['browser'] =="Safari" || $return['browser'] == "Mobile" || $return['browser'] == "")
            {
                $return['browser'] = "{$return['platform']} mobile";
            }
            break;
    }

    return $return;
} // End of Function
?>

答案 2 :(得分:4)

你听说过browscap和get_browser()吗?在我的安装上:

$info = get_browser();
echo $info->browser; // Chrome
echo $info->version; // 29.0

要使用它,请从here获取一份PHP版本的browscap.ini(例如php_browscap.ini),并在php.ini指令下的browscap中引用它,你很高兴。

答案 3 :(得分:4)

这个类/函数做得很好:

old dead link: https://github.com/diversen/coscms/blob/master/coslib/useragent.php

我用iphone和opera测试了这个。同时,您将获得运行浏览器的操作系统。)

编辑:

我可以看到这个函数有一个它自己的git repo。使用此功能,因为它已更新和维护:

https://github.com/donatj/PhpUserAgent