Installation:
composer require cravler/browscap-bundle
Add the bundle to config/bundles.php (Laravel 5.4+) or AppKernel.php (Symfony/Laravel <5.4):
// config/bundles.php
return [
// ...
Cravler\BrowscapBundle\BrowscapBundle::class => ['all' => true],
];
Publish Config (optional):
php artisan vendor:publish --tag=browscap-config
This creates config/browscap.php with default settings.
First Use Case:
Inject the Browscap service and fetch browser info from a user-agent string:
use Cravler\BrowscapBundle\Browscap\Browscap;
public function detectBrowser(Browscap $browscap)
{
$userAgent = request()->userAgent();
$browser = $browscap->getBrowser($userAgent);
return $browser->getBrowser() . ' ' . $browser->getVersion();
}
Fetching Browser Data:
// Get full Browscap object
$browser = $browscap->getBrowser($userAgent);
// Access specific properties
$browser->getBrowser(); // e.g., "Chrome"
$browser->getVersion(); // e.g., "91.0.4472.124"
$browser->getPlatform(); // e.g., "Windows"
$browser->getMajorver(); // e.g., "91"
Caching Strategy: The bundle auto-caches results for 24 hours by default. Override in config:
'cache' => [
'enabled' => true,
'ttl' => 3600, // 1 hour
],
Remote vs. Local INI:
browscap.org (default).
'remote_ini_url' => 'http://tempdownloads.browserscap.com/stream.php?BrowsCapINI',
'local_ini_path' => storage_path('browscap/browscap.ini'),
Download the INI from browscap.org and place it in storage/browscap/.Middleware Integration: Attach to middleware to enrich requests with browser data:
namespace App\Http\Middleware;
use Closure;
use Cravler\BrowscapBundle\Browscap\Browscap;
class DetectBrowser
{
protected $browscap;
public function __construct(Browscap $browscap)
{
$this->browscap = $browscap;
}
public function handle($request, Closure $next)
{
$browser = $this->browscap->getBrowser($request->userAgent());
$request->merge(['browser' => $browser]);
return $next($request);
}
}
Custom Logic:
Extend the Browscap service or create a decorator:
class CustomBrowscap extends Browscap
{
public function isMobile($userAgent)
{
$browser = $this->getBrowser($userAgent);
return in_array($browser->getPlatform(), ['iOS', 'Android', 'Windows Phone']);
}
}
Rate Limiting: Remote INI fetching may hit rate limits if called frequently. Use local INI in production:
'remote_ini_url' => null, // Disable remote fetching
'local_ini_path' => storage_path('browscap/browscap.ini'),
Outdated Data: The free Browscap INI updates weekly. For critical apps, consider:
* * * * * cd /path/to/project && php artisan browscap:update
User-Agent Spoofing: Malicious users can spoof user-agent strings. Validate critical data server-side:
if ($browser->getBrowser() === 'Unknown') {
// Handle unknown browsers or potential spoofing
}
Memory Usage: The Browscap INI is ~1MB. For high-traffic apps, ensure your server has enough memory.
Deprecation:
The get_browser() PHP function is deprecated. This bundle is a modern alternative but may evolve independently.
Check Cache: Clear cache if data seems stale:
php artisan cache:clear
php artisan config:clear
Log User-Agent: Debug mismatches by logging raw user-agent strings:
\Log::debug('User-Agent:', [$request->userAgent()]);
Validate INI File: Ensure the local INI file is readable and valid:
php artisan browscap:validate
Custom Properties:
Extend the Browscap\Browscap\Browser class to add custom methods:
namespace App\Extensions;
use Cravler\BrowscapBundle\Browscap\Browser;
class ExtendedBrowser extends Browser
{
public function isSupported()
{
return !in_array($this->getBrowser(), ['IE', 'Edge']);
}
}
Event Listeners: Listen for Browscap updates or failures:
// config/browscap.php
'events' => [
'update.success' => [YourListener::class, 'onUpdateSuccess'],
'update.failure' => [YourListener::class, 'onUpdateFailure'],
],
Testing:
Mock the Browscap service in tests:
$mockBrowser = new \Cravler\BrowscapBundle\Browscap\Browser();
$mockBrowser->setBrowser('Chrome')->setVersion('91.0');
$mockBrowscap = $this->createMock(Browscap::class);
$mockBrowscap->method('getBrowser')->willReturn($mockBrowser);
How can I help you explore Laravel packages today?