十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CodeIgniter 3 User Agent 类库实战指南:识别浏览器、移动设备与爬虫访问

CodeIgniter 3 User Agent 类库实战指南:识别浏览器、移动设备与爬虫访问 CodeIgniter 3 User Agent 类库实战指南识别浏览器、移动设备与爬虫访问【免费下载链接】CodeIgniterOpen Source PHP Framework (originally from EllisLab)项目地址: https://gitcode.com/gh_mirrors/co/CodeIgniterUser Agent 类库是 CodeIgniter 框架内置的客户端识别组件通过解析 HTTP 请求头中的User-Agent字符串帮助开发者判断访问者的浏览器类型与版本、操作系统平台、是否为移动设备或搜索引擎爬虫并进一步获取来源页Referrer、浏览器接受的语言与字符集信息。阅读完本文你将掌握 User Agent 类库的初始化方式、四个用户代理定义数组的定制方法、全部类方法的用法与返回约定并通过源码级剖析理解其底层匹配算法从而在移动端分流、SEO 统计、访问日志分析等场景中落地实践。User Agent 类库能做什么在 Web 开发中User-Agent字符串是客户端浏览器、手机、爬虫主动上报的自我描述内容形如Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.0.4) Gecko/20060613 Camino/1.0.2CodeIgniter 的 User Agent 类CI_User_agent实现于 system/libraries/User_agent.php负责解析这类字符串并输出以下信息浏览器名称与版本号如 Safari 533.20.27、Firefox 13.0平台操作系统信息Windows、Linux、Mac OS X、Android、iOS 等移动设备手机品牌或设备类型iPhone、Nokia、Samsung、PlayStation 等机器人/爬虫搜索引擎蜘蛛等Googlebot、Baiduspider、Bing 等来源与偏好来源页面Referrer、接受的Accept-Language语言列表、接受的Accept-Charset字符集列表。它本质上是一套基于正则/子串匹配的分类引擎将当前请求的 User-Agent 字符串与预置定义数组逐项比对命中后记录类型并输出规范化名称。所有定义均可在配置文件中自由扩充无需修改框架核心代码。初始化 User Agent 类库与 CodeIgniter 大多数类库一致User Agent 类在控制器中通过$this-load-library()加载$this-load-library(user_agent);加载完成后实例会以$this-agent的形式挂载到当前控制器可通过 Loader 的库加载机制全局访问。加载时构造函数即开始工作见 system/libraries/User_agent.php调用_load_agent_file()读取配置文件中的定义数组若$_SERVER[HTTP_USER_AGENT]存在将其存入$this-agent并调用_compile_data()完成平台、机器人、浏览器、移动设备的分类判定写入一条User Agent Class Initialized的 info 级日志。如果请求没有携带HTTP_USER_AGENT头类仍会正常初始化只是各类型标志位保持默认的FALSE相关取值方法返回空字符串。用户代理定义文件application/config/user_agents.php所有识别规则集中在配置文件 application/config/user_agents.php 中类库通过 system/libraries/User_agent.php 的_load_agent_file()加载它。加载逻辑支持两层配置默认读取APPPATH.config/user_agents.php若存在APPPATH.config/.ENVIRONMENT./user_agents.php环境专属配置则追加覆盖实现按development/testing/production环境差异化定制。配置文件中包含四个关联数组数组的键用于在 User-Agent 字符串中匹配的特征片段数组的值用于输出为可读名称数组变量用途匹配方式见源码$platforms操作系统/平台识别preg_quote($key)转义后正则匹配$browsers浏览器识别并提取版本键作为正则模式.*?([0-9\.])捕获版本号$mobiles移动设备识别大小写不敏感的stripos子串匹配$robots爬虫/机器人识别preg_quote($key)转义后正则匹配$platforms平台定义$platforms array( windows nt 10.0 Windows 10, windows nt 6.3 Windows 8.1, windows nt 6.1 Windows 7, android Android, iphone iOS, ipad iOS, os x Mac OS X, linux Linux, // ... );平台匹配由_set_platform()system/libraries/User_agent.php完成将每个键preg_quote转义后与 User-Agent 字符串做大小写不敏感正则比对首个命中即写入$this-platform。一个值得注意的细节是数组中同时存在windows nt 6.3 Windows 8.1等带具体版本号的键以及windows Unknown Windows OS这类兜底键因此数组顺序即匹配优先级——具体版本应排在笼统键之前。全部未命中时返回Unknown Platform。$browsers浏览器定义与版本提取// 顺序不要更改许多浏览器会在 UA 中上报多个类型须先识别子类型 $browsers array( OPR Opera, Edge Edge, Chrome Chrome, Opera.*?Version Opera, // Opera 10 上报 Opera/9.80真实版本在 Version/ 后 Opera Opera, MSIE Internet Explorer, Firefox Firefox, Safari Safari, Mozilla Mozilla, // ... );配置文件顶部特别注释强调数组顺序不应更改——许多浏览器会在同一 UA 中上报多个类型例如 Chrome 的 UA 里同时包含Mozilla/5.0与Safari/537.36因此必须把子类型Chrome、Edge、Opera排在通用兜底项Mozilla之前。_set_browser()system/libraries/User_agent.php使用模式|.$key..*?([0-9\.])|i匹配命中后置$this-is_browser TRUE用捕获组([0-9\.])提取版本号存入$this-version将定义值存入$this-browser。值得注意的特殊条目Opera.*?VersionOpera 10 的 UA 恒为Opera/9.80 (...)并追加Version/真实版本因此用正则键提取其后真实版本号这正是配置键可含正则语法的典型例证。$mobiles移动设备定义$mobiles array( motorola Motorola, nokia Nokia, nexus Nexus, iphone Apple iPhone, ipad iPad, blackberry BlackBerry, samsung Samsung, huawei Huawei, xiaomi Xiaomi, oppo Oppo, vivo Vivo, android Android, windows ce Windows CE, operamini Opera Mini, opera mini Opera Mini, mobile Generic Mobile, // 兜底 wireless Generic Mobile, j2me Generic Mobile, // ... );列表覆盖手机厂商、操作系统与移动浏览器三类并以mobile、wireless、j2me、midp、cldc等通用词作为兜底。_set_mobile()system/libraries/User_agent.php使用stripos做大小写不敏感子串匹配首个命中即返回TRUE。$robots爬虫定义// 爬虫有数百种这里只收录最常见的 $robots array( googlebot Googlebot, msnbot MSNBot, baiduspider Baiduspider, bingbot Bing, slurp Inktomi Slurp, yahoo Yahoo, yandex YandexBot, ia_archiver Alexa Crawler, MJ12bot Majestic-12, UptimeRobot UptimeRobot, // ... );如官方文档所述爬虫数量庞大数百种逐一收录并不现实因此该库仅内置最常见的蜘蛛。若你的站点常被某些未收录的爬虫访问直接在application/config/user_agents.php的$robots数组中追加键值对即可无需修改框架源码。典型实战示例类型分流与平台输出官方文档给出的标准示例完整覆盖了三种类型的判断分支与平台输出可直接放入控制器方法中使用$this-load-library(user_agent); if ($this-agent-is_browser()) { $agent $this-agent-browser(). .$this-agent-version(); } elseif ($this-agent-is_robot()) { $agent $this-agent-robot(); } elseif ($this-agent-is_mobile()) { $agent $this-agent-mobile(); } else { $agent Unidentified User Agent; } echo $agent; echo $this-agent-platform(); // 平台信息Windows、Linux、Mac 等该示例也反映了类库的内部判定顺序构造函数中的_compile_data()system/libraries/User_agent.php先固定执行_set_platform()随后按_set_robot()→_set_browser()→_set_mobile()的顺序依次尝试一旦某个方法返回TRUE立即break即同一 UA 在机器人→浏览器→移动设备三个类别中只归属首个命中的类别。这是is_browser()、is_robot()、is_mobile()三类互斥判断的底层依据。类方法参考Class Reference类型判断方法is_browser([$key NULL])返回布尔值判断当前 UA 是否为已知浏览器传入$key时可进一步判断是否为指定浏览器if ($this-agent-is_browser(Safari)) { echo You are using Safari.; } elseif ($this-agent-is_browser()) { echo You are using a browser.; }注意Safari这类字符串就是 application/config/user_agents.php 中$browsers数组的键。源码实现system/libraries/User_agent.php中$key NULL时直接返回is_browser标志否则校验$this-browser $this-browsers[$key]即当前浏览器名与定义值完全一致才返回TRUE。is_mobile([$key NULL])返回布尔值判断是否为已知移动设备可传入设备键精确匹配。典型场景是按设备类型分流视图if ($this-agent-is_mobile(iphone)) { $this-load-view(iphone/home); } elseif ($this-agent-is_mobile()) { $this-load-view(mobile/home); } else { $this-load-view(web/home); }is_robot([$key NULL])返回布尔值判断是否为已知爬虫可传入机器人键精确匹配。由于内置列表仅含最常见爬虫若发现常访问站点的机器人缺失可在配置文件的$robots数组中补充。is_referral()返回布尔值判断访问者是否从其他站点跳转而来。源码实现system/libraries/User_agent.php使用parse_url()解析HTTP_REFERER与config_item(base_url)的主机名并比较HTTP_REFERER存在且其主机与本站base_url主机不同才判定为外部来源。判定结果缓存于$this-referer同一请求内重复调用不再重新解析。信息获取方法方法返回说明browser()string浏览器名称未识别返回空字符串version()string浏览器版本号未识别返回空字符串mobile()string移动设备品牌/名称未识别返回空字符串robot()string爬虫名称未识别返回空字符串platform()string操作系统名称Linux、Windows、OS X 等未识别返回Unknown Platformreferrer()string来源页完整 URL无HTTP_REFERER时返回空字符串agent_string()string完整的原始 User-Agent 字符串其中referrer()的典型用法是配合is_referral()if ($this-agent-is_referral()) { echo $this-agent-referrer(); }而agent_string()直接返回构造/解析时保存的原始 UA如Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.0.4) Gecko/20060613 Camino/1.0.2可用于日志记录与原始审计。语言与字符集方法accept_lang([$lang en])判断访问者是否接受指定语言。默认参数为enif ($this-agent-accept_lang(en)) { echo You accept English!; }实现system/libraries/User_agent.php为in_array(strtolower($lang), $this-languages(), TRUE)的严格匹配。languages()首次调用时触发_set_languages()system/libraries/User_agent.php解析HTTP_ACCEPT_LANGUAGE用正则/(;\s?q[0-9\.])|\s/i剔除q权重值与空白后按逗号拆分全部转为小写请求头缺失时返回array(Undefined)。accept_charset([$charset utf-8])判断访问者是否接受指定字符集if ($this-agent-accept_charset(utf-8)) { echo You browser supports UTF-8!; }charsets()首次调用时由_set_charsets()system/libraries/User_agent.php解析HTTP_ACCEPT_CHARSET同样剔除q权重并按逗号拆分缺省返回array(Undefined)。可靠性提示官方文档明确指出accept_lang()与accept_charset()并非总是可靠——部分浏览器不发送语言/字符集信息即便发送也未必准确。它们更适合做渐进增强判断不应作为业务硬性依赖。languages() / charsets()分别返回访问者接受的语言列表与字符集列表数组形式未提供相应请求头时返回array(Undefined)。parse($string)解析自定义 User-Agent$this-agent-parse(Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0);parse()system/libraries/User_agent.php允许解析与当前访问者不同的自定义 UA 字符串典型场景是测试、日志重放或离线分析。它会先将is_browser、is_robot、is_mobile、browser、version、mobile、robot全部重置再写入新字符串并重新执行_compile_data()传入空字符串时仅重置不解析。测试用例验证行为与预期仓库测试 tests/codeigniter/libraries/Useragent_test.php 覆盖了上述核心行为可用于对照理解类库语义test_is_functions()以Mozilla/5.0 (Macintosh; ...) AppleWebKit/533.20.25 ... Version/5.0.4 Safari/533.20.27为基线断言is_browser()与is_browser(Safari)为TRUE、is_browser(Firefox)为FALSE、is_robot()与is_mobile()为FALSEtest_browser_info()同一 UA 下断言platform()为Mac OS X、browser()为Safari、version()为533.20.27验证.*?([0-9\.])正则对版本号的提取test_referrer()设置外部来源HTTP_REFERER后断言is_referral()为TRUE且referrer()返回完整 URL清除请求头后两者分别返回FALSE与空字符串test_accept_lang()/test_charsets()验证语言与字符集解析包括q权重剔除、Undefined兜底test_parse()传入 Firefox/Android 自定义 UA断言平台为Android、浏览器为Firefox、版本为13.0、移动设备为Android且is_mobile(android)为TRUE。测试基类CI_TestCase通过 VFS 克隆application/config/user_agents.php后实例化CI_User_agent说明配置定义是类库行为的直接输入也印证了扩展配置即可扩展识别能力的设计理念。扩展与最佳实践建议综合文档与源码给出以下几点落地建议新增识别项只需改配置在 application/config/user_agents.php 的对应数组中追加键UA 特征片段/值可读名称即可。新增平台/爬虫时键会被preg_quote转义可按字面片段书写新增浏览器时键会被当作正则模式可像Opera.*?Version一样编写正则但要留意版本捕获组([0-9\.])的配合。注意数组顺序$platforms中笼统键如windows应排在具体键如windows nt 10.0之后$browsers中通用兜底键如Mozilla必须排在子类型之后否则识别结果会被兜底项抢占。环境差异化配置可通过application/config/{ENVIRONMENT}/user_agents.php为指定环境覆盖定义例如生产环境追加内部监控爬虫的识别。结合日志与分析用agent_string()保留原始 UA用is_robot()过滤爬虫流量使访问统计更贴近真实用户。保持审慎User-Agent 可由客户端任意伪造类库判定结果仅代表UA 声称的身份涉及安全、计费等敏感逻辑时应另行核验如配合 Input 类 的 IP 与请求校验。总结CodeIgniter 的 User Agent 类库以配置文件定义 正则/子串匹配的轻量架构为浏览器、移动设备、爬虫与平台识别提供了开箱即用的能力加载一行$this-load-library(user_agent)即可通过$this-agent调用十余个语义清晰的方法。其全部识别规则集中在 application/config/user_agents.php实现位于 system/libraries/User_agent.php并有 Useragent_test.php 提供行为回归保障——理解这三者的协作关系你就能在移动端分流、SEO 分析与访问统计中快速落地一套可扩展的客户端识别方案。【免费下载链接】CodeIgniterOpen Source PHP Framework (originally from EllisLab)项目地址: https://gitcode.com/gh_mirrors/co/CodeIgniter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表