Giter Site home page Giter Site logo

browscap-php's Introduction

Browser Capabilities Project

Continuous Integration codecov

This tool is used to build and maintain browscap files.

Installation

$ git clone git://github.com/browscap/browscap.git
$ cd browscap
$ curl -s https://getcomposer.org/installer | php
$ php composer.phar install

What's changed in version 6048

  • #2535 Added recent new Apple platforms (Mac OS, iOS and iPadOS)

What's changed in version 6028

BC breaks listed

  • Interface changed for class \Browscap\Data\Factory\UserAgentFactory

What's changed in version 6027

BC breaks listed

  • Strict type hints have been added throughout. This may break some type assumptions made in earlier versions.
  • In many classes Setters and Getters have been removed, the parameters have been moved to the class constructor
  • Some classes are now final - use composition instead of inheritance

What's changed in version 6025

BC breaks listed

  • The grep command and the diff command were removed

Changes

  • The tests for integration testing the source files are split from the other tests
  • Tests on travis use the build pipeline now

Directory Structure

  • bin - Contains executable files
  • build - Contains various builds
  • resources - Files needed to build the various files, also used to validate the capabilities
  • src - The code of this project lives here
  • tests - The testing code of this project lives here

the CLI commands

There is actually only one cli command available.

build

This command is used to build a set of defined browscap files.

bin/browscap build [version]

options

  • version (required) the name of the version that should be built
  • output (optional) the directory where the files should be created
  • resources (optional) the directory where the sources for the build are located
  • coverage (optional) if this option is set, during the build information is added which can be used to generate a coverage report
  • no-zip (optional) if this option is set, no zip file is generated during the build

For further documentation on the build command, see here.

CLI Examples

You can export a new set of browscap files:

$ bin/browscap build 5020-test
Resource folder: <your source dir>
Build folder: <your target dir>
Generating full_asp_browscap.ini [ASP/FULL]
Generating full_php_browscap.ini [PHP/FULL]
Generating browscap.ini [ASP]
Generating php_browscap.ini [PHP]
...
All done.
$

Now you if you look at browscap/browscap.ini you will see a new INI file has been generated.

Usage Examples

How to build a standard set of browscap files

This example assumes that you want to build all *php_browscap.ini files.

$logger = new \Monolog\Logger('browscap'); // or maybe any other PSR-3 compatible Logger

$format = \Browscap\Formatter\FormatterInterface::TYPE_PHP; // you may choose the output format you want, the format must be already supported

$resourceFolder = 'resources/'; // please point to the resources directory inside the project
$buildFolder = ''; // choose the directory where the generated file should be written to

// If you are using one of the predefined WriterFactories, you may not choose the file names
$writerCollection = (new \Browscap\Writer\Factory\PhpWriterFactory())->createCollection($logger, $buildFolder);

$dataCollectionFactory = new \Browscap\Data\Factory\DataCollectionFactory($logger);

$buildGenerator = new BuildGenerator(
    $resourceFolder,
    $buildFolder,
    $logger,
    $writerCollection,
    $dataCollectionFactory
);

$version       = '';    // what you want to be written into the generated file
$createZipFile = false; // It is not possible yet to create a zipped version of a custom named browscap file

$buildGenerator->run($version, $createZipFile);

How to build a custom set of browscap files

If you want to build a custom set of browscap files, you may not use the predefined WriterFactories.

$logger = new \Monolog\Logger('browscap'); // or maybe any other PSR-3 compatible Logger

$format = \Browscap\Formatter\FormatterInterface::TYPE_PHP; // you may choose the output format you want, the format must be already supported

$resourceFolder = 'resources/'; // please point to the resources directory inside the project
$buildFolder = ''; // choose the directory where the generated file should be written to

$propertyHolder = new \Browscap\Data\PropertyHolder();

// build a standard version browscap.json file
$jsonFormatter = new \Browscap\Formatter\JsonFormatter($propertyHolder);
$jsonFilter    = new \Browscap\Filter\StandardFilter($propertyHolder);

$jsonWriter = new \Browscap\Writer\JsonWriter('relative path or name of the target file', $logger);
$jsonWriter->setFormatter($jsonFormatter);
$jsonWriter->setFilter($jsonFilter);

// build a lite version browscap.xml file
$xmlFormatter = new \Browscap\Formatter\XmlFormatter($propertyHolder);
$xmlFilter    = new \Browscap\Filter\LiteFilter($propertyHolder);

$xmlWriter = new \Browscap\Writer\XmlWriter('relative path or name of the target file', $logger);
$xmlWriter->setFormatter($xmlFormatter);
$xmlWriter->setFilter($xmlFilter);

$writerCollection = new \Browscap\Writer\WriterCollection();
$writerCollection->addWriter($jsonWriter);
$writerCollection->addWriter($xmlWriter);

$dataCollectionFactory = new \Browscap\Data\Factory\DataCollectionFactory($logger);

$buildGenerator = new BuildGenerator(
    $resourceFolder,
    $buildFolder,
    $logger,
    $writerCollection,
    $dataCollectionFactory
);

$version       = '';    // what you want to be written into the generated file
$createZipFile = false; // It is not possible yet to create a zipped version of a custom named browscap file

$buildGenerator->run($version, $createZipFile);

How to build a custom browscap.ini

If you want to build a custom browscap file you may choose the file name and the fields which are included.

Note: It is not possible to build a custom browscap.ini file with the CLI command.

$logger = new \Monolog\Logger('browscap'); // or maybe any other PSR-3 compatible Logger
// If using Monolog, you need specify a log handler, e.g. for STDOUT: $logger->pushHandler(new \Monolog\Handler\ErrorLogHandler());

$format = \Browscap\Formatter\FormatterInterface::TYPE_PHP; // you may choose the output format you want, the format must be already supported
$file   = null; // you may set a custom file name here
$fields = []; // choose the fields you want inside of your browscap file

$resourceFolder = 'resources/'; // please point to the resources directory inside the project
$buildFolder = ''; // choose the directory where the generated file should be written to

$writerCollection = (new \Browscap\Writer\Factory\CustomWriterFactory())->createCollection($logger, $buildFolder, $file, $fields, $format);

$dataCollectionFactory = new \Browscap\Data\Factory\DataCollectionFactory($logger);

$buildGenerator = new BuildGenerator(
    $resourceFolder,
    $buildFolder,
    $logger,
    $writerCollection,
    $dataCollectionFactory
);

$version       = ''; // version you want to be written into the generated file
$dateTime      = new \DateTimeImmutable(); // date you want to be written into the generated file
$createZipFile = false; // It is not possible yet to create a zipped version of a custom named browscap file

$buildGenerator->run($version, $dateTime, $createZipFile);

Issues and feature requests

Please report your issues and ask for new features on the GitHub Issue Tracker at https://github.com/browscap/browscap/issues

Contributing

For instructions on how to contribute see the CONTRIBUTE.md file.

License

See the LICENSE file.

browscap-php's People

Contributors

asgrim avatar bassemn avatar bryant1410 avatar cihantas avatar cziegenberg avatar daawesomep avatar damnedest avatar dependabot-preview[bot] avatar dependabot[bot] avatar dominikto avatar duxthefux avatar frederikbosch avatar garetjax avatar holtkamp avatar ianchadwick avatar jaydiablo avatar jonathaningram avatar joshuaestes avatar mimmi20 avatar mostafasoufi avatar onyxg avatar pgodel avatar quentin389 avatar scrutinizer-auto-fixer avatar slamdunk avatar smatyas avatar thadafinser avatar tmolitor-stud-tu avatar vitorbrandao avatar wanderingzombie avatar

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

browscap-php's Issues

IsBot() method

Hi guys,

is it possible to add a isBot() method which will distinguish if the user agent is a bot (crawler) because many users may need to allow bots on their sites. thanks.

get fatal error

My site will get sometimes this error:


Fatal error: Uncaught exception 'phpbrowscap\Exception' with message 'temporary file already exists' in /www/htdocs/abc/123/scripts/Browscap.php:517
Stack trace:
#0 /www/htdocs/abc/123/scripts/Browscap.php(289): phpbrowscap\Browscap->updateCache()
#1 /www/htdocs/abc/123/collect.php(112): phpbrowscap\Browscap->getBrowser(NULL, true)
#2 /www/htdocs/abc/123/collect.php(39): pageview()
#3 {main}

thrown in /www/htdocs/abc/123/scripts/Browscap.php on line 517

in my PHP-file I have the following:

lowercase = true; $current_browser = $bc->getBrowser(null,true); I think is happens when the file is called by different user in a short period. What can I do?

[3.x] RemoteLoader::getMTime returns 0 instead of timestamp

The RemoteLoader dependency retrieves the response string from the remote source and then converts it to an int.
In the case of http://browscap.org/version the resposne string is a RFC 2822 date string Mon, 01 Jun 2015 08:53:57 +0000

Fileloader\Loader\RemoteLoader

    public function getMTime()
    {
        $remoteVersionUrl = $this->getLoader()->getRemoteVerUrl();
        $remoteDatetime   = $this->getConnector()->getRemoteData($remoteVersionUrl);
        if (!$remoteDatetime) {
            throw new Exception('Bad datetime format from ' . $remoteVersionUrl, Exception::INVALID_DATETIME);
        }
        //$remoteDatetime = 'Mon, 01 Jun 2015 08:53:57 +0000'
        return (int) $remoteDatetime; //0
    }

To satisfy both browscap.org/version and original RemoteLoader::getMTime behavior I suggest using

$rfcDate = \DateTime::createFromFormat(\DateTime::RFC2822, $remoteDatetime);
$timestamp = ($rfcDate instanceof \DateTime ? $rfcDate->getTimestamp() : (int) $remoteDatetime);
if (!$timestamp) {
    throw new Exception('Bad datetime format from ' . $remoteVersionUrl, Exception::INVALID_DATETIME);
}
return $timestamp;

Chrome Canary detection not work

Hello,
I'm trying last version of Chrome Canary www.google.com/intl/en/chrome/browser/canary.html (MacOS X). There is a problem with version detection. I'm using latest version of browscap-php from composer. Best regards.

(
    [browser_name] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1932.0 Safari/537.36
    [browser_name_regex] => ^mozilla/5\.0 \(.*mac os x 10_(\d).*\) applewebkit/.* \(khtml, like gecko\).*chrome/.*safari/.*$
    [browser_name_pattern] => Mozilla/5.0 (*Mac OS X 10_9*) AppleWebKit/* (KHTML, like Gecko)*Chrome/*Safari/*
    [Parent] => Chrome Generic
    [Platform] => MacOSX
    [Platform_Version] => 10.9
    [Comment] => Chrome Generic
    [Browser] => Chrome
    [CssVersion] => 1
    [Device_Name] => PC
    [Device_Maker] => Various
    [Device_Type] => Desktop
    [Device_Pointing_Method] => mouse
    [RenderingEngine_Name] => WebKit
    [Browser_Type] => unknown
    [Version] => 0.0
    [MajorVer] => 0
    [MinorVer] => 0
    [Platform_Description] => unknown
    [Alpha] => 
    [Beta] => 
    [Win16] => 
    [Win32] => 
    [Win64] => 
    [Frames] => 
    [IFrames] => 
    [Tables] => 
    [Cookies] => 
    [BackgroundSounds] => 
    [JavaScript] => 
    [VBScript] => 
    [JavaApplets] => 
    [ActiveXControls] => 
    [isMobileDevice] => 
    [isSyndicationReader] => 
    [Crawler] => 
    [AolVersion] => 0
    [RenderingEngine_Version] => unknown
)

PHP warning message

I'm seeing the following in my php_errors.log:

PHP Notice: Undefined offset: 1543 in C:\inetpub\wwwroot\wordpress\wp-content\plugins\wp-statistics\includes\classes\Browscap.php on line 360

I think line 360 needs a quick array_key_exists() around it to avoid the error message:

if (!empty($browser[3])) {
if( array_key_exists( $browser[3], $this->_userAgents) ) {
$browser[3] = $this->_userAgents[$browser[3]];
}
}

Problem with browscap->updateCache()

exception 'ErrorException' with message 'parse error, expecting `']'' in storage/browscap/browscap.ini on line 25154
' in /vendor/browscap/browscap-php/src/phpbrowscap/Browscap.php:521

fetch command check for updates

browscap:fetch command MUST check the version vs the downloaded to avoid hitting download limit

  • The default behaviour should be to check the current version vs http://browscap.org/version-number - if we are up to date, just print a message saying the local file is up to date.
  • We should implement a force flag to override this behaviour just in case someone DOES want to re-download for whatever reason, e.g. bin/browscap browscap:fetch --force

Might be worth exposing an "are updates available" method (like in #63) so that this information can be accessible, and perhaps even as a separate command?

Getting wrong results after running updateCache()

I basically moved the following issue to browscap-php:
browscap/browscap#535

The problem is that after updating I got the following result on safari

{
    "browser_name": "Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit\/600.3.10 (KHTML, like Gecko) Version\/8.0.3 Safari\/600.3.10",
    "browser_name_regex": "^mozilla\/5\\.0 \\(.*mac os x 10_10.*\\) applewebkit\/.* \\(khtml, like gecko\\) .*version\/(\\d)\\.(\\d).* safari\/.*$",
    "browser_name_pattern": "Mozilla\/5.0 (*Mac OS X 10_10*) AppleWebKit\/* (KHTML, like Gecko) *Version\/8.0* Safari\/*",
    "Parent": 76664,
    "Platform": "Win8",
    "Platform_Version": "6.2",
    "Win64": true,
    "Comment": "Palemoon 24.5",
    "Browser": "PaleMoon",
    "Version": "24.5",
    "MajorVer": "24",
    "MinorVer": "5",
    "CssVersion": "2",
    "Alpha": false,
    "Beta": false,
    "Win16": false,
    "Win32": false,
    "Frames": false,
    "IFrames": false,
    "Tables": false,
    "Cookies": false,
    "BackgroundSounds": false,
    "JavaScript": false,
    "VBScript": false,
    "JavaApplets": false,
    "ActiveXControls": false,
    "isMobileDevice": false,
    "isTablet": false,
    "isSyndicationReader": false,
    "Crawler": false,
    "AolVersion": "0"
}

I could reproduce the issue on two MacBooks, but only for Safari. ( Chrome, Firefox were recognised correctly )
On one of the MacBooks it's been resolved by removing both the .ini and cache.php and running the updateCache() again. On both MacBooks the cache.php file is 13,439,359kb for browscap version 5037 and no exceptions are thrown while running the cacheUpdate().

Java/1.7.0_51

Hi,

I think User Agent Java/1.7.0_51 should has Browser_Type as Bot/Crawler
Please advise

Thanks

Undefined Indexes

I got the following errors, perhaps because I was trying it a new browser (Firefox 30 Beta 2)? Tested with PHP 5.5.11 (64 Bit), on Windows Server 2008 R2.

Notice: Undefined index: Palm Source in C:\wwwroot\tests\browser\vendor\browscap\browscap-php\src\phpbrowscap\Browscap.php on line 576
Call Stack

Time Memory Function Location

1 0.0010 240256 {main}( ) ..\index.php:0
2 0.0049 553064 phpbrowscap\Browscap->getBrowser( ) ..\index.php:7
3 0.0049 554144 phpbrowscap\Browscap->updateCache( ) ..\Browscap.php:289

Notice: Undefined index: in C:\wwwroot\tests\browser\vendor\browscap\browscap-php\src\phpbrowscap\Browscap.php on line 579
Call Stack

Time Memory Function Location

1 0.0010 240256 {main}( ) ..\index.php:0
2 0.0049 553064 phpbrowscap\Browscap->getBrowser( ) ..\index.php:7
3 0.0049 554144 phpbrowscap\Browscap->updateCache( ) ..\Browscap.php:289

And I also got a memory error (but that's another issue).

generating cache.php doesn't work

Hello,

I'm trying to use browscap-php and it has worked fine in the past. I did a manual update with the latest Browscap.php and it keeps generating cache.lock with nothing in it instead of cache.php. What could I be doing wrong? I'm using "PHP Version 5.3.10-1ubuntu3.9"

Investigate failing builds on OSX

I have disabled OSX builds on travis as it is failing.

Investigate why, and if we don't need to build on OSX, we won't. I don't think it's critical.

"cache.lock" won't be deleted

Hi everyone,

The cache.lock file is still present after a successful retrieval of the browscap.ini file. Therefore the next time I try to use Browscap->getBrowser() I get an Exception: "temporary file already exists".

The files:

drwxrwxrwt 8 root root 4096 aug 26 17:13 ./
drwxr-xr-x 23 root root 4096 aug 26 16:17 ../
-rw-r--r-- 1 www-data www-data 8180003 aug 26 16:47 browscap.ini
-rw-r--r-- 1 www-data www-data 0 aug 26 16:47 cache.lock

The directory they reside in is, in this case /tmp:

drwxrwxrwt 8 root root 4096 aug 26 17:06 tmp/

Do I overlook something? Or is this a problem, perhaps experienced by others too?

composer update fetch wrong version

Hi,

in my composer.json file I have this entry:

"require": {
        "php": ">=5.3.2",
            "browscap/browscap-php": ">=2.0.3",
        ...
    },

If I execute composer update I get this output

Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing browscap/browscap-php (2.0.3)
    Downloading: 100%

Generating autoload files
Compiling component files

If I show in the vendor/browscap/browscap-php/src/phpbrowscap/Browscap.php I find this:

class Browscap
{
    /**
     * Current version of the class.
     */
    const VERSION = '2.0b';

    const CACHE_FILE_VERSION = '2.0b';

So what do I have to do to get the version 2.0.3?

You can update the code to a new version.

I've pushed a new update on https://github.com/GaretJax/phpbrowscap
It bumps the version from 1.0 to 2.0b and has a lot of changes. See the list here:
https://github.com/GaretJax/phpbrowscap/blob/master/CHANGELOG.md

If you're interesting in continuing your fork of GaretJax project you may want to update your code, it should provide a lot of benefits to whoever uses this repo.

Btw, the changes I've made are directly related to what I've proposed in https://groups.google.com/d/msg/browscap-dev/FfzVNPQ268U/QNqraep9PIUJ post. Merging regular expression based on their numeric versions proved to be a huge performance upgrade. Based on those tests I'd say that it sped up the browser regex parsing by 5 to 10 times.

A boost in speed like that would be seen no matter what language you're using to parse those regular expressions. So, perhaps in a far future, get_browser() could be updated to use those more advanced regexes. A source database format that is being developed right now by @asgrim is a good start.

Version Bump

At a quick glance, my Browscap.php file from January 23 seems to be the latest version. My file has const VERSION = '2.0b';. There have been many changes since January, but the version remains the same. The file deserves a new version number.

This is a request to bump the VERSION constant and any related comments to something other than 2.0b to reflect the fact that the file has actually had some changes over the last 6 months.

Cache memory usage

I got the "Allowed memory... exhausted" error when loading the cache and allowing 128M memory in php.ini.

I've already switched to the Lite version but the cache file is still ~4M large.

Could it be a php version problem or something else?

Temporary file already exists.

I've required browscap using composer as follows:

"require": {
  "browscap/browscap-php": ">=1.0"
}

I've created the caching directory in vendor/browscap/browscap-php/cache. Next, in my code I use the following code:

$browscap = new phpbrowscap\Browscap('vendor/browscap/browscap-php/cache);
$info = $browscap->getBrowser();

And I get the error 'temporary file already exists'. The files: browscap.ini and cache.lock in the directory vendor/browscap/browscap-php/cache are created however. I've tried the suggestion of adding $browscap->doAutoUpdate = false; right after creating the browscap object, but this didn't change a thing. I've also toyed around with the cache directory rights, removing cache.lock, but leaving the browscap.ini file, and unabling it to write cache.lock: this didn't do a thing either.

What am I doing wrong in my two lines of PHP code to get this to work..?

Something not right, memory leak?

I get this error:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2329600 bytes) in path-to-Browscap.php on line 505

Line 505 is this: $browsers = parse_ini_file($ini_path, true, INI_SCANNER_RAW);

I have the latest version of browscap.ini

When using the old browscap.php (v1.0) file it works fine, tried using v2.0 from here on github but get errors, cannot get this version of the files to work. I have diff them, there are a fair few changes but not sure about what the problem is and why just these changes in the file are stopping it from working.

require PHP 5.3 -> PHP 5.5 in 2.0.5 ?

Is it possible to change the requirement to PHP 5.3 again for 2.0.x ? I guess it is very hard and bad decision to switch PHP Requirements within a minor version.

memory problems

Using your example script gives the following error:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /www/htdocs/1234/Browscap.php on line 718

PHP Version : PHP Version 5.4.26
Browscap const VERSION = '2.0b';
Browscap const CACHE_FILE_VERSION = '2.0b';

Any hint?
Thx in advance.

using quickstart ref do not work

First at all: I'am new in PHP.
If I follow the instructions on: https://github.com/GaretJax/phpbrowscap/wiki/QuickStart.
On Setup without Composer (copied code) I will get this error:
Parse error: syntax error, unexpected T_STRING, expecting T_CONSTANT_ENCAPSED_STRING or '(' in /www/htdocs/123456/byme/test.php on line 9
line 9 is: use phpbrowscap\Browscap;
It semms that my php do not know what "use" is.
What I'am doing wrong?
Sorry for that stupid question. Thx for any hint in advance.

$browscap->doAutoUpdate = false; ignored when cached not build

Hi guys,

the $browscap->doAutoUpdate = false; is getting ignored when cache is not build which kinda makes it not useful if you want to have background process to do it.

its relatively easy to fix under getBrowser() method but let me know your thoughts so can send PR across.

[3.x] Browscap::update() does nothing with new remote cache

Effectively you should be able to perform a fetch+convert or update according to the documentation.

According to the update method, it will never retrieve a new remote file if a cache does not already exist.
https://github.com/browscap/browscap-php/blob/3.x/src/Browscap.php#L408

if $cachedTime is null, it would be equal to 0
Since $remoteTime <= null is always false, it will return void, instead of loading the retrieved content.

The line should read

if ($cachedTime !== null && $remoteTime <= $cachedTime)

or to catch 0, null, or false

if (!empty($cachedTime) && $remoteTime <= $cachedTime)

[2.x] Remove php file generation from browscap-php.

The Issue

There are some performance issues with creating the PHP file from the ini files: #26

Historically, the ini files and the browscap-php were managed by completely different people. So it made sense to do the format conversion within the PHP code.

However, right now those two project are very much connected, and @asgrim is OK with pre-generating browscap-php formatted files on the browscap servers.

The goal would be to split browscap-php into two projects:

  • A backend module to pre-generate files in a compatible format.
  • A frontend module to detect browsers and just download the generated files.

You'd still be able to generate the intermediary files on your server if you wish, but by default you'd have them on the browscap project website. This way we can completely remove any issues with memory or cpu usage when in need of a file update, and clean up some code as an added bonus.

Implementation

The most optimal way to do that would be to just pre-generate the PHP files, however it can't be done if it would allow an execution of arbitrary code if incorrect files were downloaded. Right now we're just doing https://github.com/browscap/browscap-php/blob/master/src/phpbrowscap/Browscap.php#L774 which means we can't get that file automatically from an outside source.
Unless there is some very safe way to just get the arrays from that file (if they exist) and ignore all the potential bogus code, what could be done is this:

  • We'd pre-generate a simple ini file. It would contain all the data required by the php cache file, in its final format, written line by line in the order we need to save it in the php file. The data generated there would still be just data from the ini files we use now, so it would be just used for string matching, and not executed client-side.
  • When in need of a new file, the Browscap.php file would download the new ini format and then parse it, line by line, using stream functions (http://php.net/manual/en/function.fgets.php) for both reading and writing to a new PHP cache file.
  • This file should be a temporary, uniquely named file, to avoid any conflicts when writing, and only after writing is finalized, moved to replace the previous one.

Operation like that will take almost no RAM (< 1 MB, no matter the file size) and no time (stream writing and reading is extremely fast). The only reasons for any issues would be:

  • problem with downloading from the web
  • disk i/o issues

However, both of those issues are equally present in the current browscap-php version.

One additional thing to do would be to provide the downloads for specific browscap-php version, as the ini format may change in the future.

This change would completely remove any current and potential future issues with converting the ini format to PHP cache files.

Considering a need for versioning and that it's a large behavior modification it should bump up the version to 2.1 or maybe even 3.0.

Performance issue (?)

I've been using browscap-php for various projects and just implemented it for a project where it processes several UA strings consecutively. Since execution time is critical on this project I ran a few tests on browscap performance.

What struck me was that the first call to getBrowser($uaSting) takes upwards to 1/2 second. Subsequent calls are much faster, but it raises a concern for other projects, where this is part of the landing page initialisation.

Any idea why the first call takes this long? Is it the cache file loading?

Any ideas on how this can be improved?

This is a dump of 4 UA strings parsed through getBrowser. Execution time in seconds.

[hit-0-ua] => 0.44112491607666 -> Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36
[hit-8-ua] => 0.04863715171814 -> Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:32.0) Gecko/20100101 Firefox/32.0 AlexaToolbar/alxf-2.21
[hit-13-ua] => 0.010688066482544 -> Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36
[hit-32-ua] => 0.0010919570922852 -> Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53

Missing User Agents Nexus 10

Missing User Agent for Chrome on Nexus 10 with Andriod 4.4:

Version 34:
Mozilla/5.0 (Linux; Android 4.4.2; Nexus 10 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36

Version 35:
Mozilla/5.0 (Linux; Android 4.4.4; Nexus 10 Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Safari/537.3

Version 36:
Mozilla/5.0 (Linux; Android 4.4.4; Nexus 10 Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.131 Safari/537.36

Version 37:
Mozilla/5.0 (Linux; Android 4.4.4; Nexus 10 Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Safari/537.36

Version 38 is missing too:
Mozilla/5.0 (Linux; Android 4.4.4; Nexus 10 Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.114 Safari/537.36

after updating from 2.0B to 2.0.4 I have an error regarding cache.lock


Fatal error: Uncaught exception 'phpbrowscap\Exception' with message 'temporary file /www/htdocs/abc/123/cache/cache.lock already exists' in /www/htdocs/abc/123/scripts/Browscap.php:530 Stack trace: #0 /www/htdocs/abc/123/scripts/Browscap.php(300): phpbrowscap\Browscap->updateCache() #1 /www/htdocs/abc/123/collect.php(106): phpbrowscap\Browscap->getBrowser(NULL, true) #2 /www/htdocs/abc/123/collect.php(39): pageview() #3 {main}

thrown in /www/htdocs/abc/123/scripts/Browscap.php on line 530

Whats to do?

Missing Keys

Hi,
When I use this script, there are a lot of missing keys like Browser_Type, Device_Name, Device_Maker, Device_Code_Name, Device_Brand_Name & Device_Type
Please advise

Thanks

Execute PHP code from infected .ini file

I have a POC (Proof of concept) that when there is a man in the middle attack or that the browscap.org site is hacked and code is injected into the .ini file that code can be executed on sites that use this library.

When people use the "updateCache" for updating the ini file from the remote location like http://browscap.org/stream?q=BrowsCapINI it could happen.

So the browscap-php library should not trust the ini file because it's from an outside source. Therefor the .ini file must be sanitized.

I don't know if it's appropriate to put an example in this public issue. Let me know if u want an example.

Unsupported operand types

Fatal error: Unsupported operand types in /home/wstevens/application/libraries/phpbrowscap/Browscap.php on line 369

This is breaking on $browser += $value; inside of the getBrowser() function. Basically $value is NULL.

This is the serialized string:
'a:6:{i:3;N;i:4;s:11:"Chrome 34.0";i:10;s:4:"34.0";i:11;s:2:"34";i:21;s:4:"true";i:36;s:1:"3";}'

User agent is:
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36

I am only getting this error in Chrome, where the current version is 34.0.1847.131.

Things were working fine for a while, I'm not sure why I'm suddenly getting this error.

Also in Firefox 28.0, while I'm not getting this error, browser and browser version are both empty strings. The preg_match always fails.

I tried the latest version of browscap and things are still broken.

Basically browscap has suddenly become unusable.

Kind regards

PHP Parse error: syntax error, unexpected 'use' (T_USE)

Hi,
I have used composer for a long time and have been able to avoid using namespaces. This is the first library I have needed to use one. Here is my code:

use phpbrowscap\Browscap;
$bc = new Browscap($_SERVER["DOCUMENT_ROOT"].'/php/browscap_cache');
$current_browser = $bc->getBrowser();

It output's this in the log:

PHP Parse error:  syntax error, unexpected 'use' (T_USE)

Do I need to put the first line somewhere else? Thanks for any help!

PHP 5.5.1
Apache 2.4.4
Windows 8 x86

Update the readme.md file - highlight issues with get_browser.

The https://github.com/browscap/browscap-php#introduction suggests that browscap-php is a solution to fix problems with shared hostings.

However, since quite some time now, it's not just that. It's actually a better solution than get_browser() in all aspects (almost all?).

I wrote in the discussion group:

If you can switch away from get_browser() then you definitely should. This implementation is very inferior when compared to browscap-php. Not only the pure PHP implementation is way faster, especially with opcache, as you can see here: https://github.com/browscap/browscap-php#features
but also it is actually being updated, in contrary to get_browser.

I've submitted a bug here: https://bugs.php.net/bug.php?id=65550
Not surprisingly, it isn't even assigned, after half a year...

So if there are some RAM, speed issues, or problems with ini parsing, they will most likely be fixed in browscap-php and WON'T in get_browser().

To which I got an answer:

Thanks, I wasn’t aware that browscap-php is actually the better solution. The introduction on https://github.com/browscap/browscap-php sounds a bit self-deprecating, rather like “PHP has a native function but here’s a workaround for people stuck with shared hosting” :-)


IMHO this is a very valid complaint and the readme.md should be revised to reflect the fact that one is recommended to use the PHP version instead of the native one.

[2.x] Invalid INI file is processed without error

I found this problem when my IP was temporarily banned due to rate limiting at browscap.org and conent of downloaded browscap.ini was just some error message.

If conent of browscap.ini is not valid INI file, then cache.php is still created, but all internal arrays are empty.

I suggest to check count of $browsers returned from parse_ini_file() in updateCache() and if there are no records, then stop updating file.

If you find this solution valid, I can prepare pull request.

Tablet detection

Hey,

i tested the class with some different devices everything went fine but when i came to my ipad the "getBrowser()" function returns an Object where "isTablet" is set to false but "Device_Type" is "Tablet". In my Opinion the "isTablet" variable should be set to true if "Device_Type"-Check detects that the Device is an Tablet.

bool(false) on CentOS 6.5

Here is the browscap.ini location and permission are 0777:

browscap issue

here is my php.ini setup in line browscap:

browscap issue 2

here is my phpinfo();

browscap issue 3

here is the error: bool(false)
browscap issue 4

here is the code:
browscap issue 5

the file called browscap.ini is the
"lite_php_browscap.ini (4,643 KB)"

I download the file from: http://browscap.org/
and this is the link directly: http://browscap.org/stream?q=Lite_PHP_BrowsCapINI

If you need more information let me know. Also, I'll try with the others .ini files for PHP on this CentOS server. I'll put an report here...

If there are any way how I can help you let me know.

memory exhausted errors

I have been a long time users of Browscap v1.0, however, I decided to upgrade to the newest version. Now I am getting constant out of memory errors in the Browscap script.

Fatal error: Allowed memory size of 201326592 bytes exhausted (tried to allocate 32 bytes) in /www/tracker/dev/incs/Browscap.php on line 683

I have had to increase the memory limit 3 times (up to 256MB) to get it to work.

Why is this new script so inefficient on memory? is there a fixed planned as it is not sustainable to run a production server with a single php script requiring that much memory.

Increase performance of browscap 3.x

As per conversation with @jaydiablo here, I'd like to review the performance of the 3.x series.

Although we have significantly reduced the memory usage in 3.x, it now takes much longer to process.

@jaydiablo has pinpointed a potential big win:

This was the biggest win for me when I was trying to optimize crossjoin: https://github.com/crossjoin/Browscap/commit/2ee9663bd4b971c658d87f33fe780858580f7bd4 (the digit replacement in that commit is a bit overzealous, and causes tests to fail, which was fixed later https://github.com/crossjoin/Browscap/commit/afd9f8eaec3fe506ed864a93a536e2370b570922)

Investigate this and see if we can optimise similarly.

missing variable

Scrutinizer found this error:

The variable $ini_file does not exist. Did you forget to declare it?

This`was found in Browscap.php on line 304.

is the locking mechanism for the cache really working?

I noticed this library uses a cache file. My experience with file caching in PHP is that simple things like file_put_contents() versus require() or file_get_contents() often fail in multi-core environments. Speaking a multi-core server with Apache in preforking mode.

I've seen it in other libraries for example Zend_Cache_File, breaking our production environment with empty cache files whenever two processes coincidentally collide. That's why i moved everything to php_apc for good.

Now this library does not provide other caching mechanisms, so i'd like to know what measures are taken to keep it running smoothly in a high load multi-core environment.

To demonstrate, run this in the background

<?php
while (true) {
    $i = rand(1000, 9999);
    file_put_contents('c.php', "<?php echo $i;", LOCK_EX);
}

while trying to run this

<?php require 'c.php';

on my CLI i get three results nothing, "Bus error" and a number.

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.