A powerful, comprehensive PHP library for generating realistic, specification-compliant User-Agent strings.
- Realistic Generation: Generates authentic User-Agents for Chrome, Firefox, Safari, and Edge.
- Specification System: Fluent builder API to define exact requirements (device, OS, version, etc.).
- Smart Pickers: Intelligent selection of versions, models, locales, and architectures based on platform validity.
- Strategies: Multiple selection strategies (Uniform, Weighted Market Share, Round Robin, Avoid Recent).
- Profiles: Pre-configured shortcuts for common profiles (Desktop Chrome, Mobile Safari, etc.).
- Deterministic: Seed-based generation for reproducible testing.
- High Quality: 100% Type-safe, PHPStan Level 9, 99% Test Coverage.
- Documentation Hub: Canonical entrypoint for usage, architecture, flows, and reference docs.
- Usage Guide: Full documentation on generation, strategies, and shortcuts.
- Examples: Runnable scripts demonstrating all features.
- Contributing: Guide for contributors.
- Security: Vulnerability reporting policy.
composer require jooservices/useragentThe library includes a zero-dependency CLI tool for generating strings from the command line.
# Generate 1 random string
./vendor/bin/useragent
# Generate 5 strings
./vendor/bin/useragent --count=5
# Specific constraints
./vendor/bin/useragent --browser=firefox --os=windows
./vendor/bin/useragent --device=mobile --browser=safariThe easiest way to generate a User-Agent string is via the fluent static API:
use JOOservices\UserAgent\UserAgent;
// Simple random generation
echo UserAgent::generate();
// Fluent Chaining
echo UserAgent::chrome()->windows()->generate();
echo UserAgent::firefox()->linux()->generate();
echo UserAgent::safari()->mobile()->generate();
// Unique Generation (Guarantees no duplicates in a loop)
$ua = UserAgent::unique()->generate();
// Exclusion (Invert selection)
// After exclude(), every following constraint in the chain is an exclusion.
// Example: "Give me anything EXCEPT Mobile" → desktop or tablet only
echo UserAgent::exclude()->mobile()->generate();
// Example: Chrome but NOT mobile → Chrome on desktop or tablet
echo UserAgent::chrome()->exclude()->mobile()->generate();use JOOservices\UserAgent\Service\UserAgentService;
$service = new UserAgentService();
$ua = $service->generate();
echo $ua;
// Output option: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"Use pre-defined profiles for common scenarios:
use JOOservices\UserAgent\Service\Profiles\Profiles;
$profiles = new Profiles($service);
// Desktop Chrome on Windows
echo $profiles->desktopChrome->windows();
// iPhone Safari
echo $profiles->mobileSafari->iphone();
// Android Chrome
echo $profiles->androidChrome->phone();
// Random Mobile Device
echo $profiles->randomMobile();Use the builder API for precise control:
use JOOservices\UserAgent\Domain\Enums\BrowserFamily;
use JOOservices\UserAgent\Domain\Enums\DeviceType;
use JOOservices\UserAgent\Domain\Enums\OperatingSystem;
use JOOservices\UserAgent\Spec\GenerationSpec;
$spec = GenerationSpec::create()
->browser(BrowserFamily::Chrome)
->device(DeviceType::Mobile)
->os(OperatingSystem::Android)
->versionMin(100)
->locale('fr-FR')
->build();
$ua = $service->generate($spec);Runtime currently enforces: browser, device, os, engine, riskLevel, version*, locale, arch, strategy.
The fields channel, tags, weights, and randomSpec are validated but intentionally rejected during generation until full runtime support lands.
Pass a seed to generate the exact same UA every time:
$seed = 12345;
$ua1 = $service->generate($spec, seed: $seed);
$ua2 = $service->generate($spec, seed: $seed);
assert($ua1 === $ua2); // True- Service Layer:
UserAgentServiceorchestrates the generation process. - Pickers: specialized logic for selecting
Version,Model,Locale, andArch. - Templates: Browser-specific templates (Chrome, Firefox, Safari, Edge) with device/OS awareness.
- Filters: System to filter valid templates based on constraints.
- History:
LruHistoryprevents repeating recently generated UAs.
| Scope | Supported |
|---|---|
| Browsers | Chrome, Firefox, Safari, Edge |
| OS | Windows, macOS, Linux, Android, iOS, ChromeOS |
| Device types | Desktop, Mobile, Tablet |
| Notable invalid combinations | Safari + Windows, Safari + Linux, Safari + Android; Edge + Linux (desktop); Safari desktop = macOS only, Safari mobile = iOS only |
| CLI → spec | --browser → browser, --device → device, --os → os, --count → batch size, --unique → dedupe, --format → output (text/json/csv) |
Use UserAgent::supportedCombinations()->getValidCombinations() to list all valid (browser, device, OS) pairs.
| Goal | API |
|---|---|
| 100 unique mobile UAs for scraper rotation | UserAgent::batch(100, ['spec' => UserAgent::scenarioPresetMobileFirstApac(), 'unique' => true]) or UserAgent::mobile()->unique() + loop generate() |
| Deterministic UA for PHPUnit | UserAgent::seed(12345); then UserAgent::chrome()->windows()->generate() |
| Exclude Safari | UserAgent::exclude()->safari()->generate() (after exclude(), all following constraints are exclusions) |
| Start chain with no constraint | UserAgent::builder()->locale('fr-FR')->generate() |
| Same constraints, N UAs | UserAgent::chrome()->windows()->generateMany(5) or UserAgent::batch(5, ['spec' => UserAgent::chrome()->windows()->toSpec()]) |
| Weighted real-market traffic | UserAgent::generate() or UserAgent::batch(N, ['unique' => false]) |
| Browser matrix for QA | UserAgent::scenarioPresetQaBrowserMatrix() then $service->generate($spec) per spec |
See Usage guide for full examples.
- PHP 8.5+
random_int()support
MIT