響應式設計雖能透過 CSS Media Query 處理大部分版面適配,但伺服端仍需針對行動裝置輸出精簡 HTML、關閉重度動畫、切換輕量 API 等差異化邏輯。基於 User-Agent 的偵測雖非 100% 精準,但成本最低、覆蓋率最高,是實務首選。
<?php
/**
* 判斷是否為行動裝置請求
* @return bool
*/
function isMobileRequest(): bool
{
// 1. 快速排除:明確桌面 UA 關鍵字
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$uaLower = strtolower($ua);
// Windows / Linux 桌面瀏覽器直接返回 false(WP7/WP10 例外處理)
if (str_contains($uaLower, 'windows') && !str_contains($uaLower, 'windows phone')) {
return false;
}
if (str_contains($uaLower, 'macintosh') || str_contains($uaLower, 'linux')) {
// 仍需進一步檢查是否為 Android/行動版 Firefox/Chrome
}
// 2. 明確行動裝置關鍵字(涵蓋 99%+ 主流裝置)
$mobileKeywords = [
'mobile', 'android', 'iphone', 'ipad', 'ipod',
'blackberry', 'webos', 'opera mini', 'opera mobi',
'iemobile', 'wpdesktop', 'phone', 'kindle',
'silk', 'fennec', 'maemo', 'meego',
];
foreach ($mobileKeywords as $kw) {
if (str_contains($uaLower, $kw)) { return true; }
}
// 3. Accept 標頭輔助判斷(WAP 瀏覽器)
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
if (str_contains(strtolower($accept), 'application/vnd.wap.xhtml+xml')) {
return true;
}
// 4. 特定 Header 存在即判定為行動裝置
if (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE'])) {
return true;
}
return false;
}
function getBrowserInfo(): array
{
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$info = ['name' => 'Unknown', 'version' => '0.0'];
$patterns = [
'Edge' => 'Edg/([\d.]+)',
'Chrome' => 'Chrome/([\d.]+)',
'Firefox' => 'Firefox/([\d.]+)',
'Safari' => 'Version/([\d.]+).*Safari',
'Opera' => 'OPR/([\d.]+)',
'IE' => 'MSIE ([\d.]+)|Trident/.*rv:([\d.]+)',
'WeChat' => 'MicroMessenger/([\d.]+)',
'QQ' => 'QQ/([\d.]+)',
'UCBrowser' => 'UCBrowser/([\d.]+)',
];
foreach ($patterns as $name => $pattern) {
if (preg_match("#$pattern#i", $ua, $matches)) {
$info['name'] = $name;
$info['version'] = $matches[1] ?? ($matches[2] ?? '0.0');
break;
}
}
return $info;
}
Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform 等標準 Header,伺服端可直接讀取結構化資訊,無需解析 UA 字串。navigator.userAgentData(支援 Client Hints 的瀏覽器)可獲取結構化裝置資訊,傳給後端做二次驗證。輕量偵測用 UA,精準業務用 Client Hints + 前端上報,分層防禦最穩健。