Giter Club home page Giter Club logo

cbschuld / browser.php Goto Github PK

View Code? Open in Web Editor NEW
580.0 64.0 305.0 198 KB

A PHP Class to detect a user's Browser. This encapsulation provides a breakdown of the browser and the version of the browser using the browser's user-agent string. This is not a guaranteed solution but provides an overall accurate way to detect what browser a user is using.

Home Page: https://chrisschuld.com/projects/browser-php-detecting-a-users-browser-from-php/

License: MIT License

PHP 100.00%
php browser useragent user-agent

browser.php's Introduction

cbschuld/browser.php

Build Status

Helps detect the user's browser and platform at the PHP level via the user agent

Installation

You can add this library as a local, per-project dependency to your project using Composer:

composer require cbschuld/browser.php

If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:

composer require --dev cbschuld/browser.php

Typical Usage:

$browser = new Browser();
if( $browser->getBrowser() == Browser::BROWSER_FIREFOX && $browser->getVersion() >=10 ) {
	echo 'You have FireFox version 10 or greater';
}

Browser Detection

This solution identifies the following Browsers and does a best-guess on the version:

  • Opera (Browser::BROWSER_OPERA)
  • WebTV (Browser::BROWSER_WEBTV)
  • NetPositive (Browser::BROWSER_NETPOSITIVE)
  • Edge (Browser::BROWSER_EDGE)
  • Internet Explorer (Browser::BROWSER_IE)
  • Pocket Internet Explorer (Browser::BROWSER_POCKET_IE)
  • Galeon (Browser::BROWSER_GALEON)
  • Konqueror (Browser::BROWSER_KONQUEROR)
  • iCab (Browser::BROWSER_ICAB)
  • OmniWeb (Browser::BROWSER_OMNIWEB)
  • Phoenix (Browser::BROWSER_PHOENIX)
  • Firebird (Browser::BROWSER_FIREBIRD)
  • UCBrowser (Browser::BROWSER_UCBROWSER)
  • Firefox (Browser::BROWSER_FIREFOX)
  • Mozilla (Browser::BROWSER_MOZILLA)
  • Palemoon (Browser::BROWSER_PALEMOON)
  • curl (Browser::BROWSER_CURL)
  • wget (Browser::BROWSER_WGET)
  • Amaya (Browser::BROWSER_AMAYA)
  • Lynx (Browser::BROWSER_LYNX)
  • Safari (Browser::BROWSER_SAFARI)
  • Playstation (Browser::BROWSER_PLAYSTATION)
  • iPhone (Browser::BROWSER_IPHONE)
  • iPod (Browser::BROWSER_IPOD)
  • Google.s Android(Browser::BROWSER_ANDROID)
  • Google.s Chrome(Browser::BROWSER_CHROME)
  • GoogleBot(Browser::BROWSER_GOOGLEBOT)
  • Yahoo!.s Slurp(Browser::BROWSER_SLURP)
  • W3C.s Validator(Browser::BROWSER_W3CVALIDATOR)
  • BlackBerry(Browser::BROWSER_BLACKBERRY)

Operating System Detection

This solution identifies the following Operating Systems:

  • Windows (Browser::PLATFORM_WINDOWS)
  • Windows CE (Browser::PLATFORM_WINDOWS_CE)
  • Apple (Browser::PLATFORM_APPLE)
  • Linux (Browser::PLATFORM_LINUX)
  • Android (Browser::PLATFORM_ANDROID)
  • OS/2 (Browser::PLATFORM_OS2)
  • BeOS (Browser::PLATFORM_BEOS)
  • iPhone (Browser::PLATFORM_IPHONE)
  • iPod (Browser::PLATFORM_IPOD)
  • BlackBerry (Browser::PLATFORM_BLACKBERRY)
  • FreeBSD (Browser::PLATFORM_FREEBSD)
  • OpenBSD (Browser::PLATFORM_OPENBSD)
  • NetBSD (Browser::PLATFORM_NETBSD)
  • SunOS (Browser::PLATFORM_SUNOS)
  • OpenSolaris (Browser::PLATFORM_OPENSOLARIS)
  • iPad (Browser::PLATFORM_IPAD)

History and Legacy

Detecting the user's browser type and version is helpful in web applications that harness some of the newer bleeding edge concepts. With the browser type and version you can notify users about challenges they may experience and suggest they upgrade before using such application. Not a great idea on a large scale public site; but on a private application this type of check can be helpful.

In an active project of mine we have a pretty graphically intensive and visually appealing user interface which leverages a lot of transparent PNG files. Because we all know how great IE6 supports PNG files it was necessary for us to tell our users the lack of power their browser has in a kind way.

Searching for a way to do this at the PHP layer and not at the client layer was more of a challenge than I would have guessed; the only script available was written by Gary White and Gary no longer maintains this script because of reliability. I do agree 100% with Gary about the readability; however, there are realistic reasons to desire the user.s browser and browser version and if your visitor is not echoing a false user agent we can take an educated guess.

I based this solution off of Gary White's original work but have since replaced all of his original code. Either way, thank you to Gary. Sadly, I never was able to get in touch with him regarding this solution.

Testing

The testing with PHPUnit against known user agents available in tests/lists. Each file is tab delimited with the following fields:

User Agent, User Agent Type, Browser, Version, Operating System, Operating System Version

eg

Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16	Browser	Opera	12.16	Linux	Linux	
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1   Browser	Chrome	14.0.835.186	Macintosh	OS X		10_7_2

Tests can be run by phpunit:

vendor/phpunit/phpunit/phpunit

browser.php's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

browser.php's Issues

iPad returns false for isMobile?

Is the "isMobile()" call supposed to return false on the iPad?

That's what I'm getting when trying to use it, but I wasn't sure if this was intended or a bug?

The user agent is:
Mozilla/5.0 (iPad; CPU OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3

Thanks

Mac detected as iPad

My mac is erroneously being detected as an iPad ($brower->getPlatform()) .

Safari reports: iPad
Chrome reports: Apple
Firefox reports: Apple

device: MacbookPro13,2
Safari Version 10.0.1 (12602.2.14.0.7)

any help would be appreciated

Support curl & wget

Add support for curl & wget

@willemstuursma originally created work to detect curl & wget but the files were out of date; will work in his functions & tests

Undefined Offset error in browser display

     I have implemented browser.php on my project for tracking browsers and platform.When I check my browser  it will display all the browser name except

Google Chrome. It displays following error
Undefined offset: 1 in D:\wamp\www\tracker202\assert\Browser.php on line 647.
please help me how to resolve these error?

Composer best practices

Hello,

it would be nice to remove the version property of composer.json file and use git tag to release versions.

This way is the simplest way of providing stable version as long as a developement one.

UC Browser not detecting.

Its not working for UC Browser.
I have made some changes to detect UC Browser too.

/**
* Determine if the browser is UCBrowser or not (last updated 1.7)
* @return boolean True if the browser is UCBrowser otherwise false
*/

protected function checkBrowserUCBrowser()
{
    if (stripos($this->_agent, 'UCBrowser') !== false) {
        $resultant = stristr($this->_agent, 'UCBrowser');
        if (preg_match('/\//', $resultant)) {
            $aresult = explode('/', $resultant);
            if (isset($aresult[1])) {
                $aversion = explode(' ', $aresult[1]);
                $this->setVersion($aversion[0]);
            }
        } else {
            $aversion = explode(' ', stristr($resultant, 'UCBrowser'));
            if (isset($aversion[1])) {
                $this->setVersion($aversion[1]);
            }
        }
        if (stripos($this->_agent, 'Mobile') !== false) {
            $this->setMobile(true);
        } else {
            $this->setTablet(true);
        }
        $this->setBrowser(self::BROWSER_UCBROWSER);
        return true;
    }
    return false;
}

Please, review it and add/modify if necessary.

Suggestion: Getter/Setter made nicer

Hey there!
When I work with getters and setters, I really like using magic methods since they make things easyer. Here is what i'd recommend for this very, VERY awesome class!

<?php class Browser {

    // ......all the other code


    /*
     * This function will call a getter function to get the information.
     * Example: $Browser->browser;
     * This will actually call $browser->getBrowser(); - it just looks a little more natural.
     * @return mixed
    */  
    public function __get($what) {
        $method = "get".ucfirst($what);
        if(method_exists($this, $method))
            return call_user_func(array($this, $method));
        else
            return $this->$what;
    }

    /*
     * The same as above, just for functions like setUserAgent.
     * @return void
    */
    public function __set($name, $value) {
        $method = "set".ucfirst($name);
        if(method_exists($this, $method))
            return call_user_func(array($this, $method), $value);
        else
            return $this->$name;
    }

    // ......all the other code

}

Just a thought =)

Edge Mobile detected as Chrome

(This is directly related to #89)

The new chrome-based Microsoft Edge on mobile is still detected as a Chrome Browser.

I tried this on Android 10 with the official Microsoft Edge App (https://play.google.com/store/apps/details?id=com.microsoft.emmx) (App-Version: Edge 45.02.4.4931)

The user agent is:
Mozilla/5.0 (Linux; Android 10; HRY-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.116 Mobile Safari/537.36 EdgA/45.02.4.4931

I think the A in the EdgA part seems to be the problem since the latest fix only checks for Edg.


This should probably also be tested for the official Apple App (https://apps.apple.com/us/app/microsoft-edge/id1288723196) which I'm currently not able to.

Get Browser name without device?

Hi I can't seem to separate the platform and the browser name. See the browser section has "iPhone" and "iPad".
Any way to get the functionality I'd like? Help is much appreciated.

screen shot 2016-06-18 at 15 56 30

Remove closing PHP tag

As this class does not contain any HTML, accidential whitespaces in output due to them coming after the ?> can be avoided by simply removing the closing tag. PHP does only requre an opening tag - and if it finds the file's end (EOF), then it will treat the file as complete.

Its just a simple thing I saw while reading the file.

speed

I think that checking the user agent 50+ times is incorrect, you can speed up the script several times by disassembling the user agent, and then checking each parameter according to the conditions.

License conflict

Hi
At the root of the project it is indicated that the program is licenced under the MIT, but in Browser.php it still mentions the General Public License.

Can that be updated?
Mario

NameSpace

Hi
Thanks to add a namespace to your package

Consider using the PSR-4 autoloader

As title, it seems that this class still uses the classmap approach to load the Browser class in composer.json.

I think we can consider using the PSR-4 autoloader and the advantages are as follows:

  • The PSR-4 approach will have the namespace and it can avoid the class name collision.

Once this issue is accepted, I can help this issue :).

Update demonstration website

As title, it seems that the http://localhost:3000/projects/browser-php-detecting-a-users-browser-from-php/ demonstration site should be updated.

It should have a global website on the Internet to be visible for everyone.

I can support this domain and demonstration website if @cbschuld wants to do this :).

IE11 Detection broken

The recent commit 012d604 broke detection of IE11. It no longer checks for 'trident' in the user agent string as it was before, and IE11 does not contain MSIE in the user agent string. This wrongly causes getBrowser() to return "Mozilla" instead of "Internet Explorer".

Retrieved version number and PHP 8

The getVersion method is documented to return only a single period:

    /**
     * The version of the browser.
     * @return string Version of the browser (will only contain alpha-numeric characters and a period)
     */
    public function getVersion()
    {
        return $this->_version;
    }

However, it may contain multiple. E.g. '15.1.4'.

This was not really an obvious issue, until PHP 8, which changes how automatic casting works...

php -r 'var_dump("15.1.4" == 15.1);'
bool(false)

It returns false as it now does a string comparison rather than an automatic cast, if it doesn't fully match the pattern of a float (I think!!). I was relying on this, as I'm sure other users were.

This change to the setVersion method fixes it by making it only have one period section:

    /**
     * Set the version of the browser
     * @param string $version The version of the Browser
     */
    public function setVersion($version)
    {
        $this->_version = preg_replace('#^([^\.]*\.[^\.]*)\..*#', '$1', preg_replace('/[^0-9,.,a-z,A-Z-]/', '', $version));
    }

This provides us a return value that continues to work...

$ php -r 'var_dump("15.1" == 15.1);'
bool(true)

Edge showing Chrome

The getBrowser() method is showing 'Chrome' in browser Microsoft Edge (Version 104.0.1293.70)

The class is checking for Edge/ but Edge changed it to: Edg/

Googlebot is shown as iPhone

We screwed up our internal analytics by this issue.

Sample Input UserAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

Output: iPhone.

Expected Output: GoogleBot

Solution / Fix:
The parsing priority for Googlebot (and other bots) must be high.
Replace the function checkBrowsers with this:

protected function checkBrowsers()
{
    return (
        // well-known, well-used
        // Special Notes:
        // (1) Opera must be checked before FireFox due to the odd
        //     user agents used in some older versions of Opera
        // (2) WebTV is strapped onto Internet Explorer so we must
        //     check for WebTV before IE
        // (3) (deprecated) Galeon is based on Firefox and needs to be
        //     tested before Firefox is tested
        // (4) OmniWeb is based on Safari so OmniWeb check must occur
        //     before Safari
        // (5) Netscape 9+ is based on Firefox so Netscape checks
        //     before FireFox are necessary

        // common bots
        $this->checkBrowserGoogleBot() ||
        $this->checkBrowserMSNBot() ||
        $this->checkBrowserBingBot() ||
        $this->checkBrowserSlurp() ||

        $this->checkBrowserWebTv() ||
        $this->checkBrowserInternetExplorer() ||
        $this->checkBrowserOpera() ||
        $this->checkBrowserGaleon() ||
        $this->checkBrowserNetscapeNavigator9Plus() ||
        $this->checkBrowserFirefox() ||
        $this->checkBrowserChrome() ||
        $this->checkBrowserOmniWeb() ||

        // common mobile
        $this->checkBrowserAndroid() ||
        $this->checkBrowseriPad() ||
        $this->checkBrowseriPod() ||
        $this->checkBrowseriPhone() ||
        $this->checkBrowserBlackBerry() ||
        $this->checkBrowserNokia() ||

        // check for facebook external hit when loading URL
        $this->checkFacebookExternalHit() ||

        // WebKit base check (post mobile and others)
        $this->checkBrowserSafari() ||

        // everyone else
        $this->checkBrowserNetPositive() ||
        $this->checkBrowserFirebird() ||
        $this->checkBrowserKonqueror() ||
        $this->checkBrowserIcab() ||
        $this->checkBrowserPhoenix() ||
        $this->checkBrowserAmaya() ||
        $this->checkBrowserLynx() ||
        $this->checkBrowserShiretoko() ||
        $this->checkBrowserIceCat() ||
        $this->checkBrowserIceweasel() || 
        $this->checkBrowserW3CValidator() ||
        $this->checkBrowserMozilla() /* Mozilla is such an open standard that you must check it last */
    );
}

Windows Phone Issues

isMobile() is false for windows phone and Platform is windows instead of windows phone.

Please tag versions

Please create versions in github, so the project can work nicely with composer

some gaps

iPhone
unknown
Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_4 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) CriOS/28.0.1500.16 Mobile/10B350 Safari/8536.25

Safari
unknown
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.11 (KHTML, like Gecko) DumpRenderTree/0.0.0.0 Safari/536.11

iPhone
28.0
Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) CriOS/28.0.1500.16 Mobile/10B142 Safari/8536.25

Internet Explorer
9.0
Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; HTC; Radar; Orange)
("Mobile")

Edge detection

The current library doesn't detect the new Edge browser over Windows 10.

Edge is erroneously being detected as a Chrome

Hi, Edge is erroneously being detected as a Chrome (Browser::BROWSER_EDGE) .

Edge on Mac reports: Chrome
Edge on Windows reports: Chrome
Edge on Linux reports: Chrome

Edge v.79.0.309.71

Any help would be appreciated to show correct browser name.

Identify PlayStation systems

The PlayStation 3, 4 and Vita web browser share a pretty simple structure:

Mozilla/5.0 (Playstation $version[;] $firmware) AppleWebkit(......)

$version: 3, 4, Vita
$firmware: X.XX (i.e. 3.55)

The PlayStation 3 has a semi-colon, appearently, whilst Vita and 4 do not.

To classify:

    const BROWSER_PLAYSTATION = "PlayStation";
    const PLATFORM_PLAYSTATION = "Sony PlayStation";

PS 3 and 4 are "Desktop" and not mobile. Vita is mobile.

Unfortunately I am not perfectly sure of the results for the PSP.

Could they be implemented?

Wrong isTablet result for opera on Android 6 Tablet

UserAgent is "Mozilla/5.0 (Linux; Android 6.0.1; SM-T580 Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.125 Safari/537.36 OPR/43.0.2246.121183"

Result for $browser->isTablet() is false

isTablet does not detect iPad Pro

I just noticed that iPads Pro are not detected as tablets.

Here an example of an iPad Pro user agent string:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Safari/605.1.15

As far as I could read, as of today iPads Pro are same as intel macs, the only way to potentially detect them would be checking for touchscreen functionality.

Any plans, ideas or workarounds to detect iPad Pro on PHP side?

Thanks in advance.

Add support for Brave browser detection

So there is a browser called Brave which is based on the Chromium open-source.
Homepage: https://brave.com/

It's available on pretty much same OSes that Chrome is.
They are using a slightly changed User-Agent on Windows though (haven't checked linux one yet).

Windows 10 x64: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Brave Chrome/74.0.3729.157 Safari/537.36

Looks like on android they are using same User-Agent as the mobile Chrome.

Android 9: Mozilla/5.0 (Linux; Android 9; *device*) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36

I think Browser.php should add support for Brave Chrome keyword in case they change their mobile User-Agent to match the Window's scheme so it's possible to disguise mobile Chrome from Brave.

iPad unknown

Mozilla/5.0 (iPad; CPU OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) CriOS/28.0.1500.12 Mobile/10B329 Safari/8536.25

Support for Pale Moon (based on Mozilla Firefox)

There's an Open Source project called Pale Moon which primary is based earlier versions of Mozilla Firefox, now independly developed over time. Project home page: https://www.palemoon.org/

The browser mainly available on Windows & Linux platforms, other platforms are still developed.
Linux UA (Pale Moon 28.5.0): Mozilla/5.0 (X11; Linux x86_64; rv:60.9) Gecko/20100101 Goanna/4.2 Firefox/60.9 PaleMoon/28.5.0

Should add SkypeUriPreview

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) SkypeUriPreview Preview/0.5

Similar to FacebookExternalHit

iOS Browser Detection

On iOS Safari getBrowser() would return "iPhone" as Browser and (for me) "9.0" as Version, which is actually enough for my purposes, but it could still be a problem for developers that need to go further than me in detecting Browsers. But using Mozilla Firefox on iOS, again the function returns "iPhone", but isn't able to detect the Version, therefore returns "unknown". I didn't test it for other Browsers on iOS but i'm assuming that it's not possible to detect the specific browser as well.
Tested on an iPhone SE (iOS 9.3.5, newest versions of Firefox and (obviously) Safari, atm)

Unable to install via Composer

When adding Browser as a dependency in Composer, I get the following error:

[RuntimeException]
Failed to clone https://github.com/cbschuld/browser.php.git via git, https
protocols, aborting.

It appears that on packagist (https://packagist.org/packages/cbschuld/browser.php) the canonical url https://github.com/cbschuld/browser.php however it is actually https://github.com/cbschuld/Browser.php
(Not the capital B in Browser.php)

Although viewing either via a web browser doesn't seem to matter, it looks like Composer/Git does.

Is this an issue with Browser or is it a Composer or git issue?

My composer.json has
"require": {
"cbschuld/browser.php": "dev-master"
}

Cheers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.