透過分析 HTTP 請求頭中的 User-Agent 字串,可識別用戶的瀏覽器類型、版本與作業系統,進而實現差異化內容交付(如載入不同 CSS/JS、響應式佈局、統計分析)。本文提供完整的解析函數實現,涵蓋主流瀏覽器與作業系統識別邏輯,並討論現代替代方案。
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
// 例:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
User-Agent 遵循「產品/版本 (註釋) 產品/版本 ...」格式,但歷史包袱極重,需用正則逐一匹配特徵片段。
function determineBrowser(string $ua): string {
$browser = 'Unknown';
$version = '';
// 註:preg_match 區分大小寫,瀏覽器關鍵字通常區分大小寫
if (preg_match('/MSIE ([0-9.]+)/', $ua, $m) || preg_match('/Trident\/.*rv:([0-9.]+)/', $ua, $m)) {
$browser = 'Internet Explorer';
$version = $m[1];
} elseif (preg_match('/Edg\/([0-9.]+)/', $ua, $m)) { // 必須在 Chrome 之前判斷
$browser = 'Edge';
$version = $m[1];
} elseif (preg_match('/OPR\/([0-9.]+)/', $ua, $m)) {
$browser = 'Opera';
$version = $m[1];
} elseif (preg_match('/Firefox\/([0-9.]+)/', $ua, $m)) {
$browser = 'Firefox';
$version = $m[1];
} elseif (preg_match('/Chrome\/([0-9.]+)/', $ua, $m)) {
$browser = 'Chrome';
$version = $m[1];
} elseif (preg_match('/Safari\/([0-9.]+)/', $ua, $m) && !preg_match('/Chrome|Edg|OPR/', $ua)) {
$browser = 'Safari';
$version = $m[1];
} elseif (preg_match('/AppleWebKit\/([0-9.]+)/', $ua, $m)) {
$browser = 'WebKit-based';
$version = $m[1];
}
return $browser . ($version ? " $version" : '');
}
關鍵順序:Edge (Edg)、Opera (OPR) 必須在 Chrome 之前判斷,因它們的 UA 都包含
Chrome/字樣。
function determinePlatform(string $ua): string {
$platform = 'Unknown';
// Windows 版本映射
if (preg_match('/Windows NT ([0-9.]+)/', $ua, $m)) {
$versions = [
'10.0' => 'Windows 10/11',
'6.3' => 'Windows 8.1',
'6.2' => 'Windows 8',
'6.1' => 'Windows 7',
'6.0' => 'Windows Vista',
'5.2' => 'Windows Server 2003/XP x64',
'5.1' => 'Windows XP',
'5.0' => 'Windows 2000',
];
$platform = $versions[$m[1]] ?? "Windows NT $m[1]";
}
// macOS
elseif (preg_match('/Mac OS X ([0-9_.]+)/', $ua, $m)) {
$ver = str_replace('_', '.', $m[1]);
$platform = "macOS $ver";
}
// iOS
elseif (preg_match('/CPU (iPhone|iPad) OS ([0-9_]+)/', $ua, $m)) {
$platform = $m[1] . ' iOS ' . str_replace('_', '.', $m[2]);
}
// Android
elseif (preg_match('/Android ([0-9.]+)/', $ua, $m)) {
$platform = "Android $m[1]";
}
// Linux
elseif (stripos($ua, 'Linux') !== false) {
$platform = 'Linux';
}
// 其他 Unix-like
elseif (preg_match('/(FreeBSD|OpenBSD|NetBSD|SunOS|AIX|HP-UX|IRIX)/', $ua, $m)) {
$platform = $m[1];
}
return $platform;
}
<?php
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$browser = determineBrowser($ua);
$platform = determinePlatform($ua);
echo "Browser: $browser
";
echo "Platform: $platform
";
// 業務應用範例:根據瀏覽器載入不同 Polyfill
if (stripos($browser, 'Internet Explorer') !== false) {
echo '';
}
?>
手寫正則難以覆蓋海量 UA 變體(爬蟲、智能電視、車載系統、新版瀏覽器等)。生產環境強烈建議使用:
composer require ua-parser/uap-php
use UAParser\Parser;
$parser = Parser::create();
$result = $parser->parse($ua);
echo $result->ua->family; // Chrome
echo $result->ua->major; // 120
echo $result->os->family; // Windows
echo $result->os->major; // 10
echo $result->device->family; // Other
composer require whichbrowser/parser
use WhichBrowser\Parser;
$browser = new Parser($ua);
echo $browser->browser->name; // Chrome
echo $browser->os->name; // Windows
echo $browser->device->type; // desktop
echo $browser->isMobile(); // false
Chrome 89+ 開始推廣 User-Agent Client Hints,將 UA 拆解為結構化請求頭:
Sec-CH-UA:瀏覽器品牌與版本Sec-CH-UA-Mobile:是否移動裝置Sec-CH-UA-Platform:作業系統Sec-CH-UA-Platform-Version:OS 版本PHP 獲取方式:
$ua_brand = $_SERVER['HTTP_SEC_CH_UA'] ?? '';
$ua_mobile = $_SERVER['HTTP_SEC_CH_UA_MOBILE'] ?? '?0';
$ua_platform = $_SERVER['HTTP_SEC_CH_UA_PLATFORM'] ?? '';
UA-CH 需伺服器端響應
Accept-CH頭聲明需求的提示,且受隱私預算限制。建議雙軌並行:優先解析 UA-CH,回退傳統 UA 解析。
composer update 獲取最新規則庫。User-Agent 解析是「看似簡單、實則深坑」的領域。站在巨人肩膀上(成熟解析庫),才能專注業務邏輯而非正則維護。