Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Tests

on:
push:
branches: [ main, master ]
tags: [ 'v*' ]
pull_request:
branches: [ main, master ]

jobs:
test:
runs-on: ubuntu-latest

strategy:
matrix:
php-version: ['8.0', '8.1', '8.2', '8.3']

name: PHP ${{ matrix.php-version }}

steps:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring
coverage: none

- name: Validate composer.json
run: composer validate --strict --no-check-lock

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ hashFiles('**/composer.json') }}
restore-keys: |
${{ runner.os }}-php-${{ matrix.php-version }}-

- name: Install dependencies
run: composer install --prefer-dist --no-progress

- name: Run test suite
run: vendor/bin/phpunit
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
vendor
.phpunit.result.cache
/phpunit.xml
composer.lock
.DS_Store
12 changes: 0 additions & 12 deletions .travis.yml

This file was deleted.

29 changes: 29 additions & 0 deletions Browser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
/**
* Browser.php v2.x Backward Compatibility Shim
*
* This file provides backward compatibility for users who include Browser.php directly
* without using Composer's autoloader.
*
* For new projects, please use the namespaced class:
* use cbschuld\Browser;
* $browser = new Browser();
*
* Legacy usage (deprecated but still works):
* require_once 'Browser.php';
* $browser = new Browser();
*/

// Include the actual Browser class
require_once __DIR__ . '/src/Browser.php';

// Create global alias for backward compatibility
if (!class_exists('Browser', false)) {
class_alias('cbschuld\\Browser', 'Browser');
}

// Optional: Trigger deprecation notice (uncomment if desired)
// trigger_error(
// 'Using the global Browser class is deprecated. Please use cbschuld\\Browser instead.',
// E_USER_DEPRECATED
// );
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,36 @@ changes when it socially makes sense.

## [Unreleased]

## [2.0.0] - 2025-08-31
### Added
- PSR-4 autoloading with `cbschuld` namespace
- Return type declarations on key methods (setVersion, checkBrowserEdge, etc.)
- `compareVersion()` method for PHP 8+ compatible version comparisons
- Enhanced Edge browser detection (supports Edge/, Edg/, EdgA/, EdgiOS/ patterns)
- Root-level Browser.php shim for non-Composer backward compatibility
- GitHub Actions CI pipeline (replaces Travis CI)
- Support metadata in composer.json
- Comprehensive upgrade documentation (UPGRADING.md)

### Changed
- **BREAKING**: Minimum PHP version is now 8.0 (was 7.2)
- **BREAKING**: Added return type declarations to key methods (may affect extenders)
- **BREAKING**: Class is now namespaced as `cbschuld\Browser`
- Updated PHPUnit to 9.6 for broad PHP 8.x compatibility
- Updated phpunit.xml.dist to PHPUnit 9.6 schema
- Fixed fgetcsv escape parameter for PHP 8.1+ compatibility
- Removed composer.lock from repository (library best practice)

### Removed
- Support for PHP 7.x
- Travis CI configuration (.travis.yml)
- Composer branch alias

### Migration
- See UPGRADING.md for detailed migration instructions
- Backward compatibility maintained via automatic class aliasing
- Non-Composer users can still use direct includes

## [1.9.4] - 2019-07-09
### Added
- Added better support for Firefox Mobile
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright 2013 - 2019 Chris Schuld <chris@chrisschuld.com>
Copyright 2013 - 2025 Chris Schuld <chris@chrisschuld.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
80 changes: 66 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,69 @@
# cbschuld/browser.php

[![Build Status](https://travis-ci.org/cbschuld/Browser.php.png?branch=master)](https://travis-ci.org/cbschuld/Browser.php)
[![Tests](https://github.com/cbschuld/Browser.php/actions/workflows/tests.yml/badge.svg)](https://github.com/cbschuld/Browser.php/actions/workflows/tests.yml)

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](https://getcomposer.org/):
### Via Composer (Recommended)

composer require cbschuld/browser.php
```bash
composer require cbschuld/browser.php
```

For development only:
```bash
composer require --dev cbschuld/browser.php
```

### Direct Download

Download `Browser.php` and include it in your project:
```php
require_once '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:
## Usage

composer require --dev cbschuld/browser.php
### Modern Usage (v2.0+, Recommended)

```php
use cbschuld\Browser;

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

## Typical Usage:
### Legacy Usage (Still Supported)

```php
// Works via automatic aliasing - no namespace needed
$browser = new Browser();
if( $browser->getBrowser() == Browser::BROWSER_FIREFOX && $browser->getVersion() >=10 ) {
echo 'You have FireFox version 10 or greater';
if ($browser->getBrowser() == Browser::BROWSER_FIREFOX && $browser->getVersion() >= 10) {
echo 'You have Firefox version 10 or greater';
}
```

### Version Comparison (PHP 8+ Compatible)

```php
use cbschuld\Browser;

$browser = new Browser();

// Recommended approach for version comparison
if ($browser->compareVersion('15.0', '>=')) {
echo 'Modern browser detected';
}

// Multiple comparisons
if ($browser->getBrowser() == Browser::BROWSER_CHROME &&
$browser->compareVersion('90', '>=')) {
echo 'Modern Chrome detected';
}
```

Expand Down Expand Up @@ -53,11 +95,11 @@ This solution identifies the following Browsers and does a best-guess on the ver
* Playstation (`Browser::BROWSER_PLAYSTATION`)
* iPhone (`Browser::BROWSER_IPHONE`)
* iPod (`Browser::BROWSER_IPOD`)
* Google.s Android(`Browser::BROWSER_ANDROID`)
* Google.s Chrome(`Browser::BROWSER_CHROME`)
* 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`)
* Yahoo!'s Slurp(`Browser::BROWSER_SLURP`)
* W3C's Validator(`Browser::BROWSER_W3CVALIDATOR`)
* BlackBerry(`Browser::BROWSER_BLACKBERRY`)

## Operating System Detection
Expand Down Expand Up @@ -87,7 +129,7 @@ Detecting the user's browser type and version is helpful in web applications tha

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.
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.

Expand All @@ -106,7 +148,17 @@ Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.1 (KHTML, like Ge
Tests can be run by phpunit:

```bash
vendor/phpunit/phpunit/phpunit
vendor/bin/phpunit
```

## Upgrading from v1.x

See [UPGRADING.md](UPGRADING.md) for detailed migration instructions.

**Quick Summary:**
- v2.0 requires PHP 8.0+
- Class is now namespaced: `cbschuld\Browser`
- Backward compatibility maintained via automatic aliasing
- Use `compareVersion()` for reliable version comparisons


110 changes: 110 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Upgrading from v1.x to v2.0

## Breaking Changes

### PHP Version Requirement
- **Minimum PHP version**: 8.0+ (was 7.2+)
- **Reason**: Enables modern PHP features and improved performance

### Namespace Introduction
- **New namespace**: `cbschuld\Browser`
- **Migration path**: See usage examples below

### Return Type Declarations
- Added return type hints to protected methods
- **Impact**: If you extend the `Browser` class and override protected methods, you'll need to add matching return types
- **Example**: `protected function checkBrowserEdge(): bool` (was `protected function checkBrowserEdge()`)

## Migration Guide

### For Composer Users

#### Option 1: Use Namespaced Class (Recommended)
```php
// Old (v1.x)
$browser = new Browser();

// New (v2.x) - Recommended
use cbschuld\Browser;
$browser = new Browser();
```

#### Option 2: Keep Using Global Class (Backward Compatible)
```php
// Still works in v2.x due to automatic aliasing
$browser = new Browser();
```

### For Non-Composer Users

#### Direct Include (Still Works)
```php
// Include the root Browser.php file
require_once '/path/to/Browser.php';
$browser = new Browser(); // Works via automatic aliasing
```

#### Manual Namespace Include
```php
// Include the namespaced file directly
require_once '/path/to/src/Browser.php';
use cbschuld\Browser;
$browser = new Browser();
```

### For Class Extenders

If you extend the Browser class, update your method signatures:

```php
// Old (v1.x)
class MyBrowser extends Browser {
protected function checkBrowserEdge() {
// your implementation
}
}

// New (v2.x)
use cbschuld\Browser;

class MyBrowser extends Browser {
protected function checkBrowserEdge(): bool {
// your implementation
}
}
```

## New Features in v2.0

### Improved Version Comparison
Use the new `compareVersion()` method for PHP 8+ compatible version comparisons:

```php
$browser = new Browser();
// Instead of: $browser->getVersion() >= '10.0'
// Use: $browser->compareVersion('10.0', '>=')
```

### Enhanced Edge Detection
- Better support for modern Edge user agents
- Handles Edge/, Edg/, EdgA/, and EdgiOS/ patterns

## Troubleshooting

### Tests Failing After Upgrade
- Ensure you're using PHP 8.0+
- Run `composer install` to get compatible dependencies
- Update any custom test classes that extend Browser

### Class Not Found Errors
- For Composer users: Run `composer dump-autoload`
- For direct includes: Ensure you're including the root `Browser.php` file

### Version Comparison Issues
- Replace direct version comparisons with `compareVersion()` method
- This handles PHP 8's stricter type comparison rules

## Need Help?

- [GitHub Issues](https://github.com/cbschuld/Browser.php/issues)
- [Documentation](https://github.com/cbschuld/Browser.php)
Loading