Question

I have a simple php script to detect browser name and os. Everything goes well, except for OPERA, that shows as Chrome. Here is my code:

<?php



    $user_agent = $_SERVER['HTTP_USER_AGENT'];

    function getOS() { 

        global $user_agent;

        $os_platform    =   'Unknown OS Platform';

        $os_array       =   array (

            '/windows nt 6.2/i'     => 'Windows 8',
            '/windows nt 6.1/i'     => 'Windows 7',
            '/windows nt 6.0/i'     => 'Windows Vista',
            '/windows nt 5.2/i'     => 'Windows Server 2003/XP x64',
            '/windows nt 5.1/i'     => 'Windows XP',
            '/windows xp/i'         => 'Windows XP',
            '/windows nt 5.0/i'     => 'Windows 2000',
            '/windows me/i'         => 'Windows ME',
            '/win98/i'              => 'Windows 98',
            '/win95/i'              => 'Windows 95',
            '/win16/i'              => 'Windows 3.11',
            '/macintosh|mac os x/i' => 'Mac OS X',
            '/mac_powerpc/i'        => 'Mac OS 9',
            '/linux/i'              => 'Linux',
            '/ubuntu/i'             => 'Ubuntu',
            '/iphone/i'             => 'iPhone',
            '/ipod/i'               => 'iPod',
            '/ipad/i'               => 'iPad',
            '/android/i'            => 'Android',
            '/blackberry/i'         => 'BlackBerry',
            '/webos/i'              => 'Mobile'

        );

        foreach ($os_array as $regex => $value) { 

            if (preg_match($regex, $user_agent)) $os_platform = $value;

        }   

        return $os_platform;

    }



    function getBrowser() {

        global $user_agent;

        $browser        =   "Unknown Browser";

        $browser_array  =   array (

            '/msie/i'       => 'Internet Explorer',
            '/firefox/i'    => 'Firefox',
            '/safari/i'     => 'Safari',
            '/chrome/i'     => 'Chrome',
            '/opera/i'      => 'Opera',
            '/netscape/i'   => 'Netscape',
            '/maxthon/i'    => 'Maxthon',
            '/konqueror/i'  => 'Konqueror',
            '/mobile/i'     => 'Handheld Browser'

        );

        foreach ($browser_array as $regex => $value) { 

            if (preg_match($regex, $user_agent)) $browser = $value;

        }

        return $browser;

    }



    $user_os        =   getOS();
    $user_browser   =   getBrowser();

    $device_details =   '<strong>Browser: </strong>' . $user_browser . '<br /><strong>Operating System: </strong>' . $user_os;

    print_r($device_details);

    echo('<br /><br /><br />' . $_SERVER['HTTP_USER_AGENT']);



?>

I changed the $browser_array by adding /OPR/i as another regex for opera and placed the Chrome regex after the 2 Opera regex's:

    $browser_array  =   array (

        '/msie/i'       => 'Internet Explorer',
        '/firefox/i'    => 'Firefox',
        '/safari/i'     => 'Safari',
        '/OPR/i'        => 'Opera',
        '/opera/i'      => 'Opera',
        '/chrome/i'     => 'Chrome',
        '/netscape/i'   => 'Netscape',
        '/maxthon/i'    => 'Maxthon',
        '/konqueror/i'  => 'Konqueror',
        '/mobile/i'     => 'Handheld Browser'

    );

here is Chrome UA:

Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36

And here is Opera UA:

Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36 OPR/15.0.1147.141
Was it helpful?

Solution

Code logic : it finds Opera first in the loop, but then meets "Chrome", which also matches. So the last result found is kept. I suggest :

foreach ($browser_array as $regex => $value) { 

    if (preg_match($regex, $user_agent) && $browser == "Unknown Browser")
        $browser = $value;

}

This way, if the browser has already been found, it won't change it to the new value. Make sure to sort your array correctly though.

In your case, this code would find Opera first (matching OPR), and ignore Chrome afterwards (even though Opera matches with "Chrome"). The problem with that code is that this time, Chrome will be the problem (it will be detected as Opera). You should use more specific REGEX.

The fact that some browsers are partially signed as others is history-related. Some browsers take their code from others, and are therefore recognized differently.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top