[Resolved] Grabbing visitors OS, state, isp, city info

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

[Resolved] Grabbing visitors OS, state, isp, city info

Post by kaisellgren »

Hi,

Everything else is fine, except OS, state, isp, city that I haven't managed to gather. Any ideas?
Last edited by kaisellgren on Sat Apr 07, 2007 11:33 am, edited 1 time in total.
bubblenut
Forum Newbie
Posts: 20
Joined: Sat Feb 03, 2007 4:16 am
Location: London

Post by bubblenut »

The OS you can usually grab from the user agent http header ($_SERVER['HTTP_USER_AGENT']).
The state, city and isp would all inferred from the ip address, there are quite a few ip location database services around.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Just be aware that the correlating data on the IP address may be off by hundreds or thousands of miles.
Mightywayne
Forum Contributor
Posts: 237
Joined: Sat Dec 09, 2006 6:46 am

Post by Mightywayne »

(in fact, it 90% of the time is off by atleast a few miles)
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post by onion2k »

My current IP address will probably resolve to the USA somewhere despite the fact I'm sitting in my office on the south coast of the UK.

The only way to accurately get someone's location is to ask them what it is. And even then they might lie.
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Post by kaisellgren »

Not very easy to get certain information from HTTP_USER_AGENT string. It may vary a lot ... http://en.wikipedia.org/wiki/User_agent#Browsers
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

You know there is a function called get_browser()..

I've posted an alternate for it previously.. search for it if you run into problems with that function.
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Post by kaisellgren »

feyd wrote:You know there is a function called get_browser()..

I've posted an alternate for it previously.. search for it if you run into problems with that function.
As long as I know your server need to have a file or something to be used with that function?

I need a stable system that works on EVERY server without complicated 3rd party file installations. The method must not need to be 99% exact, I need it to grab the OS that visitors are running on. Let's say that the method needs to be 75-80% accurate.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

You are trying to find the users Operating System?
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Post by kaisellgren »

Everah wrote:You are trying to find the users Operating System?
Yes.

All other is fine now.
bubblenut
Forum Newbie
Posts: 20
Joined: Sat Feb 03, 2007 4:16 am
Location: London

Post by bubblenut »

Check out Net_UserAgent_Detect as well.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

kaisellgren wrote:As long as I know your server need to have a file or something to be used with that function?

I need a stable system that works on EVERY server without complicated 3rd party file installations. The method must not need to be 99% exact, I need it to grab the OS that visitors are running on. Let's say that the method needs to be 75-80% accurate.
Complicated third party file installation? :lol:

I'll have to assume you haven't looked at my variant of it.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

I ran across this class once and have used it locally for testing. It might help you. Save the entire snippet and call it from your server:

browser-detection-test.php

Code: Select all

<?php
/**
* @version $Id$
* @package dinke.net
* @copyright &copy; 2005 Dinke.net
* @author Dragan Dinic <dragan@dinke.net>
*/

/**
* Browser Detection class
* contains common static method for
* getting browser version and os
*
* It only support recent and popular browsers
* and doesn't recognize bots (like google, yahooo etc)
* for more browser support you might want to try some other class
*
* usage
* <code>
* $browser = Browser_Detection::get_browser($_SERVER['HTTP_USER_AGENT']);
* $os = Browser_Detection::get_os($_SERVER['HTTP_USER_AGENT']);
* </code>
* @access public
*/
class Browser_Detection
{
    
    /**
     * Get browsername and version
     * @param string user agent    
     * @return string browser name and version or false if unrecognized
     * @static
     * @access public
     */
    function get_browser($useragent)
    {
        //check for most popular browsers first
        //unfortunately that's ie. We also ignore opera and netscape 8
        //because they sometimes send msie agent
        if(strpos($useragent,"MSIE") !== false && strpos($useragent,"Opera") === false && strpos($useragent,"Netscape") === false)
        {
            //deal with IE
            $found = preg_match("/MSIE ([0-9]{1}\.[0-9]{1,2})/",$useragent,$mathes);
            if($found)
            {
                return "Internet Explorer " . $mathes[1];
            }
        }
        elseif(strpos($useragent,"Gecko"))
        {
            //deal with Gecko based
            
            //if firefox
            $found = preg_match("/Firefox\/([0-9]{1}\.[0-9]{1}(\.[0-9])?)/",$useragent,$mathes);
            if($found)
            {
                return "Mozilla Firefox " . $mathes[1];
            }
            
            //if Netscape (based on gecko)
            $found = preg_match("/Netscape\/([0-9]{1}\.[0-9]{1}(\.[0-9])?)/",$useragent,$mathes);
            if($found)
            {
                return "Netscape " . $mathes[1];
            }
            
            //if Safari (based on gecko)
            $found = preg_match("/Safari\/([0-9]{2,3}(\.[0-9])?)/",$useragent,$mathes);
            if($found)
            {
                return "Safari " . $mathes[1];
            }
            
            //if Galeon (based on gecko)
            $found = preg_match("/Galeon\/([0-9]{1}\.[0-9]{1}(\.[0-9])?)/",$useragent,$mathes);
            if($found)
            {
                return "Galeon " . $mathes[1];
            }
            
            //if Konqueror (based on gecko)
            $found = preg_match("/Konqueror\/([0-9]{1}\.[0-9]{1}(\.[0-9])?)/",$useragent,$mathes);
            if($found)
            {
                return "Konqueror " . $mathes[1];
            }        

            //no specific Gecko found
            //return generic Gecko
            return "Gecko based";                    
        }
        
        elseif(strpos($useragent,"Opera") !== false)
        {
            //deal with Opera
            $found = preg_match("/Opera[\/ ]([0-9]{1}\.[0-9]{1}([0-9])?)/",$useragent,$mathes);
            if($found)
            {
                return "Opera " . $mathes[1];
            }
        }
        elseif (strpos($useragent,"Lynx") !== false)
        {
            //deal with Lynx            
            $found = preg_match("/Lynx\/([0-9]{1}\.[0-9]{1}(\.[0-9])?)/",$useragent,$mathes);
            if($found)
            {
                return "Lynx " . $mathes[1];
            }
            
        }
        elseif (strpos($useragent,"Netscape") !== false)
        {
            //NN8 with IE string
            $found = preg_match("/Netscape\/([0-9]{1}\.[0-9]{1}(\.[0-9])?)/",$useragent,$mathes);
            if($found)
            {
                return "Netscape " . $mathes[1];
            }
        }
        else
        {
            //unrecognized, this should be less than 1% of browsers (not counting bots like google etc)!
            return false;
        }
    }
    
    /**
     * Get browsername and version
     * @param string user agent    
     * @return string os name and version or false in unrecognized os
     * @static
     * @access public
     */
    function get_os($useragent)
    {        
        $useragent = strtolower($useragent);
        
        //check for (aaargh) most popular first        
        //winxp
        if(strpos("$useragent","windows nt 5.1") !== false)
        {
            return "Windows XP";            
        }
        elseif (strpos("$useragent","windows 98") !== false)
        {
            return "Windows 98";
        }
        elseif (strpos("$useragent","windows nt 5.0") !== false)
        {
            return "Windows 2000";
        }
        elseif (strpos("$useragent","windows nt 5.2") !== false)
        {
            return "Windows 2003 server";
        }
        elseif (strpos("$useragent","windows nt 6.0") !== false)
        {
            return "Windows Vista";
        }
        elseif (strpos("$useragent","windows nt") !== false)
        {
            return "Windows NT";
        }
        elseif (strpos("$useragent","win 9x 4.90") !== false && strpos("$useragent","win me"))
        {
            return "Windows ME";
        }
        elseif (strpos("$useragent","win ce") !== false)
        {
            return "Windows CE";
        }
        elseif (strpos("$useragent","win 9x 4.90") !== false)
        {
            return "Windows ME";
        }
        elseif (strpos("$useragent","mac os x") !== false)
        {
            return "Mac OS X";
        }
        elseif (strpos("$useragent","macintosh") !== false)
        {
            return "Macintosh";
        }
        elseif (strpos("$useragent","linux") !== false)
        {
            return "Linux";
        }
        elseif (strpos("$useragent","freebsd") !== false)
        {
            return "Free BSD";
        }
        elseif (strpos("$useragent","symbian") !== false)
        {
            return "Symbian";
        }
        else
        {
            return false;
        }
    }
}

$browser = Browser_Detection::get_browser($_SERVER['HTTP_USER_AGENT']);
if($browser !== false)
{
    echo "Your browser is $browser <br />";
}

$os = Browser_Detection::get_os($_SERVER['HTTP_USER_AGENT']);

if($os !== false)
{
    echo "Your OS is $os <br />";
}

?>
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

I figured I geek around with that class a little bit. Here it is in PHP 5, a little nicer...

Code: Select all

<?php
/**
 * User_Agent_Detector is used to gather information about the users browser 
 * and operating system.
 *
 * This is not a flashy whiz-bang kind of class, but it works fairly well
 * if all you need is to fetch is the users browser and operating system.
 *
 * Usage:
 * <code>
 * The easiest way to use the class is to instantiate it:
 *      $uad = new User_Agent_Detector();
 * This will echo out a single line of text along the lines of:
 *         Browser: Mozilla Firefox 2.0.0 Operating System: Windows XP
 * To prevent the echo, pass a boolean false to the constructor
 *      $uad = new User_Agent_Detector(false);
 *
 * The class can also be instantiated and the browser and os fetched with:
 *      $browser = $uad->get_browser();
 *      $os = $uad->get_os();
 *
 * The browser and os can also be displayed by calling display()
 *      $uad->display('<p>', '</p>', '<br />');
 * The display() method takes three params: opentag, closetag, separator
 * </code>
 * @version 0.1
 * @package User_Agent_Detector
 * @copyright None
 * @license Creative Commons Attribution License 3.0 {@link http://creativecommons.org/licenses/by/3.0/}
 * @author Robert Gonzalez <robert@everah.com>
 * @author Dragan Dinic <dragan@dinke.net>
 */
class User_Agent_Detector
{
    /**
     * The users browser
     *
     * @var string
     * @access public
     */
    public $browser;
    
    /**
     * The users operating system
     *
     * @var string
     * @access public
     */
    public $os;
    
    /**
     * The users complete user agent identifier
     *
     * @var string
     * @access private
     */
    private $useragent;
    
    /**
     * Class constructor
     *
     * @author Robert Gonzalez <robert@everah.com>
     * @access public
     * @param boolean $echo True displays on construction
     */
    public function __construct($echo = true)
    {
        // Set the user agent
        $this->useragent = $this->set_useragent();
        
        // Set the rest of the vars
        $this->initialize();
        
        // Should we display immediately?
        if ($echo)
        {
            // If we were able to get the useragent render it
            if ($this->useragent !== false)
            {
                $this->display();
            }
            else // Otherwise puke
            {
                $this->error();
            }
        }
    }
    
    /**
     * Initialze all two of the class properties
     *
     * @author Robert Gonzalez <robert@everah.com>
     * @access private
     */
    private function initialize()
    {
        $this->set_browser();
        $this->set_os();
    }
    
    /**
     * Output what we know in a clean little outputter
     *
     * @author Robert Gonzalez <robert@everah.com>
     * @access public
     * @param string $opentag The HTML tag to use to open the string
     * @param string $closetag The HTML tag to use to close the string
     * @param string $separator The HTML tag to use to separate the browser from OS in the string
     * @return string A string displaying the users browser and OS
     */
    public function display($opentag = '', $closetag = '', $separator = ' ')
    {
        echo $opentag . 'Browser: ' . $this->browser . $separator . 'Operating System: ' . $this->os . $closetag;
    }
    
    /**
     * Output a generic error message
     *
     * @access private
     * @author Robert Gonzalez <robert@everah.com>
     * @return string A generic error message
     * @todo Maybe allow for custom error messaging - shouldn't be that hard to implement
     */
    private function error()
    {
        echo 'We were unable to detect your browser and operating system';
    }
    
    /**
     * Gets the users browser information
     *
     * @author Robert Gonzalez <robert@everah.com>
     * @access public
     * @return string The users browser
     */
    public function get_browser()
    {
        return $this->browser;
    }
    
    /**
     * Gets the users operating system
     *
     * @author Robert Gonzalez <robert@everah.com>
     * @access public
     * @return string The users operating system
     */
    public function get_os()
    {
        return $this->os;
    }
    
    /**
     * Sets the users complete user agent string
     *
     * @author Robert Gonzalez <robert@everah.com>
     * @access private
     * @return string The users user agent on success, boolean false on failure
     */
    private function set_useragent() 
    {
        $useragent = null;
        
        if (isset($_SERVER['HTTP_USER_AGENT'])) 
        {
            $useragent = $_SERVER['HTTP_USER_AGENT'];
        } 
        else 
        {
            $useragent = getenv('HTTP_USER_AGENT');
        }
        
        return !is_null($useragent) ? $useragent : false;
    }
    
    /**
     * Get browsername and version
     * 
     * @author Robert Gonzalez <robert@everah.com>
     * @access public
     */
    private function set_browser()
    {
        $this->browser = $this->get_browser_name();
    }
    
    /**
     * Get browsername and version
     * 
     * @author Dragan Dinic <dragan@dinke.net>
     * @access private
     * @return string browser name and version or false if unrecognized
     */
    private function get_browser_name()
    {
        $useragent = $this->useragent;
        
        //check for most popular browsers first
        //unfortunately that's ie. We also ignore opera and netscape 8
        //because they sometimes send msie agent
        if (strpos($useragent, 'MSIE') !== false && strpos($useragent, 'Opera') === false && strpos($useragent, 'Netscape') === false)
        {
            //deal with IE
            if (preg_match('/MSIE ([0-9]{1}\.[0-9]{1,2})/', $useragent, $matches))
            {
                return 'Internet Explorer ' . $matches[1];
            }
        }
        elseif (strpos($useragent, 'Gecko'))
        {
            //deal with Gecko based
            
            //if firefox
            if (preg_match('/Firefox\/([0-9]{1}\.[0-9]{1}(\.[0-9])?)/', $useragent, $matches))
            {
                return 'Mozilla Firefox ' . $matches[1];
            }
            
            //if Netscape (based on gecko)
            if (preg_match('/Netscape\/([0-9]{1}\.[0-9]{1}(\.[0-9])?)/', $useragent, $matches))
            {
                return 'Netscape ' . $matches[1];
            }
            
            //if Safari (based on gecko)
            if (preg_match('/Safari\/([0-9]{2,3}(\.[0-9])?)/', $useragent, $matches))
            {
                return 'Safari ' . $matches[1];
            }
            
            //if Galeon (based on gecko)
            if (preg_match('/Galeon\/([0-9]{1}\.[0-9]{1}(\.[0-9])?)/', $useragent, $matches))
            {
                return 'Galeon ' . $matches[1];
            }
            
            //if Konqueror (based on gecko)
            if (preg_match('/Konqueror\/([0-9]{1}\.[0-9]{1}(\.[0-9])?)/', $useragent, $matches))
            {
                return 'Konqueror ' . $matches[1];
            }        

            //no specific Gecko found
            //return generic Gecko
            return 'Gecko based';                    
        }
        elseif (strpos($useragent, 'Opera') !== false)
        {
            //deal with Opera
            if (preg_match('/Opera[\/ ]([0-9]{1}\.[0-9]{1}([0-9])?)/', $useragent, $matches))
            {
                return 'Opera ' . $matches[1];
            }
        }
        elseif (strpos($useragent, 'Lynx') !== false)
        {
            //deal with Lynx            
            if (preg_match('/Lynx\/([0-9]{1}\.[0-9]{1}(\.[0-9])?)/', $useragent, $matches))
            {
                return 'Lynx ' . $matches[1];
            }
        }
        elseif (strpos($useragent, 'Netscape') !== false)
        {
            //NN8 with IE string
            if (preg_match('/Netscape\/([0-9]{1}\.[0-9]{1}(\.[0-9])?)/', $useragent, $matches))
            {
                return 'Netscape ' . $matches[1];
            }
        }
        else
        {
            //unrecognized, this should be less than 1% of browsers (not counting bots like google etc)!
            return false;
        }
    }
    
    /**
     * Sets the OS property
     * 
     * @author Robert Gonzalez <robert@everah.com>
     * @access private
     */
    private function set_os()
    {
        $this->os = $this->get_os_name();
    }
    
    /**
     * Get browsername and version
     *
     * @author Dragan Dinic <dragan@dinke.net>
     * @access private
     * @param string user agent    
     * @return string os name and version or false in unrecognized os
     */
    private function get_os_name()
    {        
        $useragent = strtolower($this->useragent);
        
        //check for (aaargh) most popular first        
        //winxp
        if (strpos($useragent, 'windows nt 5.1') !== false)
        {
            return 'Windows XP';            
        }
        elseif (strpos($useragent, 'windows 98') !== false)
        {
            return 'Windows 98';
        }
        elseif (strpos($useragent, 'windows nt 5.0') !== false)
        {
            return 'Windows 2000';
        }
        elseif (strpos($useragent, 'windows nt 5.2') !== false)
        {
            return 'Windows 2003 server';
        }
        elseif (strpos($useragent, 'windows nt 6.0') !== false)
        {
            return 'Windows Vista';
        }
        elseif (strpos($useragent, 'windows nt') !== false)
        {
            return 'Windows NT';
        }
        elseif (strpos($useragent, 'win 9x 4.90') !== false && strpos($useragent, 'win me'))
        {
            return 'Windows ME';
        }
        elseif (strpos($useragent, 'win ce') !== false)
        {
            return 'Windows CE';
        }
        elseif (strpos($useragent, 'win 9x 4.90') !== false)
        {
            return 'Windows ME';
        }
        elseif (strpos($useragent, 'mac os x') !== false)
        {
            return 'Mac OS X';
        }
        elseif (strpos($useragent, 'macintosh') !== false)
        {
            return 'Macintosh';
        }
        elseif (strpos($useragent, 'linux') !== false)
        {
            return 'Linux';
        }
        elseif (strpos($useragent, 'freebsd') !== false)
        {
            return 'Free BSD';
        }
        elseif (strpos($useragent, 'symbian') !== false)
        {
            return 'Symbian';
        }
        else
        {
            return false;
        }
    }
}

$stats = new User_Agent_Detector(false);
echo $stats->browser . ' Is the browser as discovered by the class.<br />';
echo $stats->os . ' Is the os as discovered by the class.<br /><br />';
$stats->display('<p>', '</p>', '<br />');
?>
Yes, it can be improved. But it will give you the OS and Browser.
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Post by kaisellgren »

That is freakin' neat my friend, thank you a lot! :)
Post Reply