最可靠方法是用$_server[‘http_user_agent’]提取ua字符串,需先校验非空再转小写匹配;安卓需同时含’android’和’mobile’,ios用’iphone’或’ipod’,微信需’micromessenger’加’miniprogram’等组合特征。

用 $_SERVER['HTTP_USER_AGENT'] 提取原始 UA 字符串最可靠
php 没有内置的“设备类型”判断函数,所有检测都基于 $_SERVER['HTTP_USER_AGENT']。这个值由浏览器发送,虽可伪造,但生产环境里仍是唯一可用依据。注意:不能依赖 $_SERVER['HTTP_X_FORWARDED_FOR'] 或 IP 段判断设备,完全无效。
常见错误是直接用 strpos() 查找关键词却忽略大小写,导致安卓设备漏判;或未过滤空 UA(如某些爬虫、命令行 curl 请求),引发 Warning。
- 始终先检查
isset($_SERVER['HTTP_USER_AGENT']) && !empty($_SERVER['HTTP_USER_AGENT']) - 统一转小写再匹配:
stripos($ua, 'mobile')比strpos(strtolower($ua), 'mobile')更安全 - 避免只靠
'mobile'判断——部分 PC 浏览器(如 chrome DevTools 切换移动模式)也会带该词
识别移动端的关键 UA 特征串有哪些
不是所有含 “mobile” 的都是真手机。真正可靠的组合特征更稳定:
- 安卓设备:同时含
'android'且含'mobile'(排除 Android 平板或桌面版 Chrome) - iOS 移动端:含
'iphone'或'ipod'('ipad'默认归为平板,需单独处理) - 微信内置浏览器:含
'micromessenger'且含'miniprogram'或不含'windows phone'(防误判旧 WinPhone) - QQ 浏览器移动端:含
'mqqbrowser'且含'mobile'
别碰 'wii'、'blackberry' 这类已淘汰 UA,加了反而增加维护负担。
立即学习“PHP免费学习笔记(深入)”;
get_browser() 函数不推荐用于设备判断
get_browser() 依赖 browscap.ini 文件,它只识别浏览器品牌和版本,对“是否为手机”无定义字段。即使开启 enable_dl,返回的 ismobiledevice 也极不可靠——例如多数华为/小米自带浏览器不在 browscap 数据库中,一律返回 false。
更实际的问题:browscap.ini 更新滞后,手动更新易出错,且解析过程有明显性能开销(每次调用都需正则匹配数百条规则)。
- 若已有 legacy 代码在用,至少缓存结果:
Static $browser = NULL; if ($browser === null) $browser = get_browser(null, true); - 新项目直接放弃,用轻量正则或字符串匹配替代
简单可复用的判断函数示例
以下函数不依赖扩展,兼容 PHP 5.6+,覆盖主流场景:
function isMobileDevice() { $ua = $_SERVER['HTTP_USER_AGENT'] ?? ''; if (!$ua) return false; $ua = strtolower($ua); return ( strpos($ua, 'android') !== false && strpos($ua, 'mobile') !== false || strpos($ua, 'iphone') !== false || strpos($ua, 'ipod') !== false || strpos($ua, 'ucweb') !== false && strpos($ua, 'mobile') !== false || strpos($ua, 'qiyu') !== false // 360 手机浏览器 ); }
注意:iPad 默认不进此函数,如需区分平板,得额外加 strpos($ua, 'ipad') !== false 并结合屏幕宽度 js 补充判断——UA 层面无法 100% 确认 iPad 是手持还是外接键盘模式。
真实项目里,设备类型只是第一层分流,后续常要配合 Accept 头、前端上报的 window.screen 或服务端渲染策略共同决策,单靠 UA 做跳转容易翻车。