Mobile_Detect 是 PHP 社群最廣泛使用的行動裝置偵測庫,透過分析 User-Agent 字串識別裝置類型、作業系統、瀏覽器。本文涵蓋安裝配置、核心 API、進階用法、效能優化、快取策略、常見誤區,並對比現代替代方案(Client Hints、WURFL、DeviceAtlas),助你選擇最適合的偵測策略。
# Composer 安裝(推薦)
composer require mobiledetect/mobiledetectlib
# 或手動下載
# https://github.com/serbanghita/Mobile-Detect
<?php
require_once 'vendor/autoload.php';
use Detection\MobileDetect;
$detect = new MobileDetect();
// 基本判斷
if ($detect->isMobile()) {
// 手機或平板
}
if ($detect->isTablet()) {
// 平板
}
// 排除平板,僅手機
if ($detect->isMobile() && !$detect->isTablet()) {
// 純手機
}
$detect->isMobile(); // 手機或平板
$detect->isTablet(); // 平板
$detect->isDesktop(); // 桌機(非行動裝置)
$detect->isPhone(); // 手機(排除平板)
$detect->isComputer(); // 同 isDesktop()
$detect->isiOS(); // iOS (iPhone/iPad/iPod)
$detect->isAndroidOS(); // Android
$detect->isWindowsPhoneOS(); // Windows Phone
$detect->isBlackBerryOS(); // BlackBerry
$detect->isPalmOS(); // Palm
$detect->isSymbianOS(); // Symbian
$detect->isFeaturePhone(); // 功能機(非智慧型手機)
$detect->isiPhone(); // iPhone
$detect->isiPad(); // iPad
$detect->isiPod(); // iPod Touch
$detect->isKindle(); // Kindle
$detect->isSilk(); // Kindle Fire Silk 瀏覽器
$detect->isPlaybook(); // BlackBerry PlayBook
$detect->isNexus(); // Nexus 系列
$detect->isGalaxy(); // Samsung Galaxy
$detect->isPixel(); // Google Pixel
$detect->isChrome(); // Chrome
$detect->isSafari(); // Safari
$detect->isFirefox(); // Firefox
$detect->isIE(); // Internet Explorer
$detect->isEdge(); // Edge
$detect->isOpera(); // Opera
$detect->isUCBrowser(); // UC Browser
$detect->isSamsungBrowser(); // Samsung Browser
version('iPhone'); // 如 '15.4'
$detect->version('iOS'); // 如 '16.5'
$detect->version('Android'); // 如 '13'
$detect->version('Chrome'); // 如 '119.0.6045.105'
$detect->version('Safari'); // 如 '16.4'
is('iPhone'); // 等同 isiPhone()
$detect->is('Bot'); // 機器人
$detect->is('Crawler'); // 爬蟲
// 取得所有可用規則
$rules = $detect->getRules(); // ['iPhone' => regex, 'iPad' => regex, ...]
$properties = $detect->getProperties(); // 版本提取規則
// 取得 User-Agent
$ua = $detect->getUserAgent();
$ua = $detect->getHttpHeaders(); // 完整 HTTP 標頭陣列
setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 16_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1');
$detect->setHttpHeaders([
'HTTP_USER_AGENT' => '...',
'HTTP_ACCEPT' => 'text/html,...',
// 可加入 Client Hints 標頭
'HTTP_SEC_CH_UA' => '"Google Chrome";v="119", "Chromium";v="119"',
'HTTP_SEC_CH_UA_MOBILE' => '?0',
'HTTP_SEC_CH_UA_PLATFORM' => '"Windows"',
]);
<?php
// 以 UA 字串雜湊為 Key
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$cacheKey = 'device_detect:' . md5($ua);
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$cached = $redis->get($cacheKey);
if ($cached !== false) {
$deviceInfo = json_decode($cached, true);
} else {
$detect = new MobileDetect();
$deviceInfo = [
'is_mobile' => $detect->isMobile(),
'is_tablet' => $detect->isTablet(),
'is_desktop' => $detect->isDesktop(),
'is_ios' => $detect->isiOS(),
'is_android' => $detect->isAndroidOS(),
'is_iphone' => $detect->isiPhone(),
'is_ipad' => $detect->isiPad(),
'browser' => $detect->getBrowser(), // 需自行實作或用 getRules 遍歷
'version' => $detect->version($detect->getBrowser()),
'ua' => $ua,
];
$redis->setex($cacheKey, 86400, json_encode($deviceInfo)); // 快取 1 天
}
// 使用 $deviceInfo
if ($deviceInfo['is_mobile']) {
// 載入行動版模板、縮圖、簡化功能
}
<?php
// Laravel Middleware 範例
namespace App\Http\Middleware;
use Closure;
use Detection\MobileDetect;
use Illuminate\Support\Facades\Cache;
class DetectDevice
{
public function handle($request, Closure $next)
{
$ua = $request->header('User-Agent');
$key = 'device:' . md5($ua);
$device = Cache::remember($key, 86400, function () use ($ua) {
$detect = new MobileDetect();
$detect->setUserAgent($ua);
return [
'type' => $detect->isMobile() ? ($detect->isTablet() ? 'tablet' : 'phone') : 'desktop',
'os' => $detect->isiOS() ? 'ios' : ($detect->isAndroidOS() ? 'android' : 'other'),
'browser' => $this->getBrowser($detect),
'is_bot' => $detect->is('Bot'),
];
});
// 共享給視圖
view()->share('device', $device);
$request->attributes->set('device', $device);
return $next($request);
}
private function getBrowser(MobileDetect $detect): string
{
foreach (['Chrome', 'Firefox', 'Safari', 'Edge', 'Opera', 'UCBrowser', 'SamsungBrowser'] as $browser) {
if ($detect->is($browser)) return strtolower($browser);
}
return 'unknown';
}
}
<?php
// 根據裝置輸出不同尺寸圖片 URL
function responsiveImageUrl(string $baseUrl, array $device): string
{
$params = [];
if ($device['type'] === 'phone') {
$params['w'] = 400;
$params['q'] = 70;
} elseif ($device['type'] === 'tablet') {
$params['w'] = 800;
$params['q'] = 80;
} else {
$params['w'] = 1200;
$params['q'] = 90;
}
return $baseUrl . '?' . http_build_query($params);
}
// 視圖中
<img src="<?= responsiveImageUrl($product->image, $device) ?>" alt="<?= $product->name ?>>
| 問題 | 原因 | 解決 |
|---|---|---|
| 新裝置無法識別 | 規則庫過舊 | 定期 `composer update`、關注 GitHub releases |
| User-Agent 可偽造 | 客戶端可任意修改 | 關鍵邏輯勿單靠 UA,結合 Client Hints、行為分析 |
| 效能瓶頸(正則匹配慢) | 每請求遍歷數百規則 | Redis 快取 UA 結果、預熱常見 UA |
| 平板誤判為手機 | UA 字串相似 | 優先檢查 `isTablet()`,再檢查 `isPhone()` |
| 版本號不準 | 實驗性功能、UA 格式多變 | 僅供參考,勿用於關鍵業務判斷 |
| Bot 誤判為行動裝置 | 部分爬蟲 UA 包含 Mobile | 先檢查 `is('Bot')` 或維護 Bot UA 白名單 |
| 方案 | 原理 | 優點 | 缺點 | 成本 |
|---|---|---|---|---|
| Mobile_Detect | UA 正則匹配 | 免費、開源、易用、PHP 原生 | UA 可偽造、需維護規則、正則效能 | 免費 |
| Client Hints (CH) | 瀏覽器主動發送結構化標頭 | 標準化、不可偽造(需權限)、精確版本/型號 | 需 HTTPS、用戶授權、舊瀏覽器不支援、Safari 支援有限 | 免費 |
| WURFL (ScientiaMobile) | 龐大裝置資料庫 + API | 極高準確度、豐富屬性(螢幕尺寸、硬體規格)、企業支援 | 商業授權昂貴、需外部 API/本地資料庫同步 | 高 |
| DeviceAtlas (Afilias) | 裝置資料庫 + 快速查找 | 極快、準確、支援 Client Hints、CDN 邊緣部署 | 商業授權、整合複雜度較高 | 高 |
| 51Degrees | 模式匹配 + 資料庫 | 開源版可用、效能好、.NET/Java/PHP/Node 支援 | 免費版資料較舊、商業版昂貴 | 中/高 |
| UAParser.js (前端) | 前端 JS 解析 UA | 零後端成本、即時、可結合指紋 | 可被禁用/偽造、增加前端體積 | 免費 |
<!-- HTML 頁面頭部啟用 Client Hints -->
<meta http-equiv="Accept-CH" content="Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA-Model, Sec-CH-UA-Full-Version-List">
<!-- 或 Nginx: add_header Accept-CH "Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform" always; -->
<?php
// PHP 解析 Client Hints
function parseClientHints(): array
{
$hints = [];
$map = [
'HTTP_SEC_CH_UA' => 'brands',
'HTTP_SEC_CH_UA_MOBILE' => 'mobile',
'HTTP_SEC_CH_UA_PLATFORM' => 'platform',
'HTTP_SEC_CH_UA_MODEL' => 'model',
'HTTP_SEC_CH_UA_FULL_VERSION_LIST' => 'versions',
];
foreach ($map as $serverKey => $name) {
if (isset($_SERVER[$serverKey])) {
$hints[$name] = $_SERVER[$serverKey];
}
}
// 解析 brands: '"Google Chrome";v="119", "Chromium";v="119"'
if (isset($hints['brands'])) {
preg_match_all('/"([^"]+)";v="([^"]+)"/', $hints['brands'], $matches);
$hints['brands_parsed'] = array_combine($matches[1], $matches[2]);
}
return $hints;
}
// 結合 UA + Client Hints 雙重保險
$device = array_merge(
['ua_based' => $mobileDetectResult],
['ch_based' => parseClientHints()]
);
裝置偵測是響應式設計、精準行銷、風控反欺詐的基礎設施。理解 User-Agent 的局限性、擁抱 Client Hints 標準、根據業務價值選擇適合的偵測方案,才能在準確度、效能、成本三角中找到最佳平衡點。