Installation
composer require acasademont/wurfl
Ensure php >= 8.0 and ext-json are available.
Configuration Publish the config file:
php artisan vendor:publish --provider="Wurfl\WurflServiceProvider" --tag="config"
Update config/wurfl.php with your WURFL API key (free tier available at ScientiaMobile).
First Use Case Detect a user agent string and fetch capabilities:
use Wurfl\Wurfl;
$wurfl = app(Wurfl::class);
$device = $wurfl->getDevice('Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1');
// Get a specific capability (e.g., screen resolution)
$width = $device->getCapability('resolution_width');
$height = $device->getCapability('resolution_height');
// Or get all capabilities as an array
$capabilities = $device->getAllCapabilities();
Middleware for Device Detection Create middleware to auto-detect and store device capabilities in the request:
namespace App\Http\Middleware;
use Closure;
use Wurfl\Wurfl;
class DetectDevice
{
public function handle($request, Closure $next)
{
$wurfl = app(Wurfl::class);
$device = $wurfl->getDevice($request->userAgent());
$request->merge(['device' => $device]);
return $next($request);
}
}
Register in app/Http/Kernel.php:
protected $middleware = [
\App\Http\Middleware\DetectDevice::class,
];
Dynamic View Adjustments Use device capabilities to modify Blade templates:
@if($device->isTablet())
<link rel="stylesheet" href="{{ asset('css/tablet.css') }}">
@elseif($device->isMobile())
<link rel="stylesheet" href="{{ asset('css/mobile.css') }}">
@endif
API Response Customization Return device-specific responses in controllers:
public function getData(Request $request)
{
if ($request->device->isMobile()) {
return response()->json(['data' => $this->mobileData()]);
}
return response()->json(['data' => $this->desktopData()]);
}
Caching for Performance Cache device detection results to avoid repeated API calls:
$device = Cache::remember("wurfl_{$userAgent}", now()->addHours(1), function() use ($wurfl, $userAgent) {
return $wurfl->getDevice($userAgent);
});
API Rate Limits
config/wurfl.php:
'api' => [
'timeout' => 5, // seconds
'retries' => 3,
],
User Agent Parsing Edge Cases
try {
$device = $wurfl->getDevice($userAgent);
} catch (\Wurfl\Exceptions\DeviceNotFoundException $e) {
$device = $wurfl->getDevice('unknown'); // Fallback
}
Capability Availability
if ($device->hasCapability('is_wireless')) {
$isWireless = $device->getCapability('is_wireless');
}
AGPL License Implications
Log Unknown Devices Log unrecognized user agents for manual review:
try {
$device = $wurfl->getDevice($userAgent);
} catch (\Wurfl\Exceptions\DeviceNotFoundException $e) {
\Log::warning("Unknown device: {$userAgent}");
$device = $wurfl->getDevice('unknown');
}
Verify API Key Test connectivity with a simple request:
$wurfl = app(Wurfl::class);
$device = $wurfl->getDevice('test'); // Should return a default device
Check Capability Names
Use the WURFL Capabilities List to verify capability names (e.g., resolution_width vs. screen_width).
Custom Device Rules
Extend the Wurfl\Device class to add custom logic:
namespace App\Extensions;
use Wurfl\Device;
class CustomDevice extends Device
{
public function isLegacy()
{
return $this->getCapability('os_name') === 'Symbian';
}
}
Bind the extension in a service provider:
$this->app->bind(Wurfl\Device::class, App\Extensions\CustomDevice::class);
Local WURFL File
For offline use, configure a local WURFL file in config/wurfl.php:
'local_file' => base_path('wurfl/wurfl.xml'),
Download the file from ScientiaMobile (requires a paid plan).
Batch Processing Process multiple user agents efficiently:
$userAgents = ['UA1', 'UA2', 'UA3'];
$devices = $wurfl->getDevices($userAgents); // Returns array of Device objects
How can I help you explore Laravel packages today?