donatj/phpuseragentparser
Lightweight PHP user-agent parser for detecting modern browsers and platforms from UA strings. Tiny codebase (<200 lines, 3 regexes), fast and accurate (including tricky IE versions). Composer-ready, 100% unit-tested, with optional object wrapper.
Installation:
composer require donatj/phpuseragentparser
Basic Usage (procedural):
use donatj\UserAgent\parse_user_agent;
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
$parsed = parse_user_agent($userAgent);
echo $parsed['platform']; // e.g., "Macintosh"
echo $parsed['browser']; // e.g., "Chrome"
Basic Usage (object-oriented):
use donatj\UserAgent\UserAgentParser;
$parser = new UserAgentParser();
$ua = $parser->parse($_SERVER['HTTP_USER_AGENT'] ?? '');
echo $ua->platform(); // e.g., "Macintosh"
echo $ua->browser(); // e.g., "Chrome"
echo $ua->browserVersion(); // e.g., "120.0.0"
Detect mobile vs. desktop traffic in a Laravel middleware:
use donatj\UserAgent\UserAgentParser;
public function handle($request, Closure $next)
{
$parser = new UserAgentParser();
$ua = $parser->parse($request->userAgent());
if ($ua->isMobile()) {
// Redirect or serve mobile-specific content
}
return $next($request);
}
Parse user agents from incoming requests (e.g., in controllers, middleware, or services):
public function show(Request $request)
{
$parser = new UserAgentParser();
$ua = $parser->parse($request->userAgent());
if ($ua->isBot()) {
return response()->json(['message' => 'Bot detected'], 403);
}
return view('home', ['browser' => $ua->browser()]);
}
Use parsed data for feature flags or A/B testing:
if ($ua->browser() === 'Safari' && $ua->platform() === 'iPhone') {
// Enable iOS-specific features
}
Avoid reprocessing the same user agent string repeatedly (e.g., in a service layer):
class UserAgentService
{
protected $cache = [];
public function parse(string $userAgent): UserAgent
{
if (!isset($this->cache[$userAgent])) {
$this->cache[$userAgent] = (new UserAgentParser())->parse($userAgent);
}
return $this->cache[$userAgent];
}
}
Extend the Request class or use a trait to add parsing methods:
trait UserAgentParsing
{
public function userAgentParser(): UserAgentParser
{
return new UserAgentParser();
}
public function isMobile(): bool
{
return $this->userAgentParser()->parse($this->userAgent())->isMobile();
}
}
Log parsed user agent data for analytics:
$logger->info('User Agent', [
'platform' => $ua->platform(),
'browser' => $ua->browser(),
'version' => $ua->browserVersion(),
'is_bot' => $ua->isBot(),
]);
Register the parser as a singleton in AppServiceProvider:
public function register()
{
$this->app->singleton(UserAgentParser::class, function () {
return new UserAgentParser();
});
}
Inject the parser into controllers or services:
use donatj\UserAgent\UserAgentParser;
class AnalyticsController
{
public function __construct(protected UserAgentParser $parser) {}
public function index()
{
$ua = $this->parser->parse(request()->userAgent());
// ...
}
}
Create middleware to block or redirect bots:
public function handle($request, Closure $next)
{
$ua = (new UserAgentParser())->parse($request->userAgent());
if ($ua->isBot()) {
return response()->json(['error' => 'Access denied'], 403);
}
return $next($request);
}
Extend the parser for project-specific needs (e.g., legacy browser support):
class CustomUserAgentParser extends UserAgentParser
{
public function isLegacyBrowser(): bool
{
$browser = $this->parse($this->userAgent)->browser();
return in_array($browser, ['MSIE', 'Firefox', 'Safari']);
}
}
if ($ua->browser() === 'Chrome' && str_contains($userAgent, 'Brave')) {
logger()->warning('Brave detected as Chrome', ['user_agent' => $userAgent]);
}
// iPadOS 13+ cannot be distinguished from macOS
if ($ua->platform() === 'Macintosh' && str_contains($userAgent, 'iPad')) {
logger()->info('Potential iPadOS 13+ detected as macOS');
}
// Note: OS version detection is unreliable; avoid using this for critical logic.
$osVersion = $ua->osVersion(); // May return null or inaccurate data
parse_user_agent() is deprecated in favor of \donatj\UserAgent\parse_user_agent().// Old (deprecated)
$ua = parse_user_agent($userAgent);
// New
$ua = \donatj\UserAgent\parse_user_agent($userAgent);
donatj\UserAgent\Browsers for comparisons:
if ($ua->browser() === \donatj\UserAgent\Browsers::EDGE) {
// Correct
}
Debug undetected user agents by logging raw strings:
logger()->debug('Undetected User Agent', [
'raw' => $userAgent,
'parsed' => $ua->toArray(),
]);
Test with known problematic user agents:
$testCases = [
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0',
'Mozilla/5.0 (iPad; CPU OS 13_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/120.0.0.0 Mobile/15E148 Safari/605.1',
];
foreach ($testCases as $uaString) {
$ua = (new UserAgentParser())->parse($uaString);
logger()->info('Test Result', ['user_agent' => $uaString, 'parsed' => $ua->toArray()]);
}
The package is actively maintained; check for new releases:
composer show donatj/phpuseragentparser
Extend the parser by adding new regex patterns or constants:
// Add a custom platform (e.g., "CustomOS")
\donatj\UserAgent\Platforms::add('CustomOS', '/Custom
How can I help you explore Laravel packages today?