You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP解析User Agent异常:设备为空时未输出预期提示

User Agent解析器逻辑错误排查

问题描述

我正在开发一个简易User Agent解析器,但当使用以下两个User Agent字符串时:

Mozilla/5.0 (Linux; Android 9 ; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36

或

Mozilla/5.0 (Linux; Android 9 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36

浏览器始终显示$OS和$osArr[1]的值,而非预期的“Device unknown”提示。以下是我的PHP代码:

<?php
$user_agent = "Mozilla/5.0 (Linux; Android 9 ; SM-577) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36";


$osStart = strpos($user_agent, "(") + 1;
$osEnd = strpos($user_agent, ";", $osStart); 
$osInfo = substr($user_agent, $osStart, $osEnd - $osStart); 
$osArr = explode("; ", $osInfo); 
$os = $osArr[0]; 

// 提取设备信息
$deviceStart = strpos($user_agent, ";", $osEnd) + 2; 
$deviceEnd = strpos($user_agent, ")", $deviceStart); 
$device = substr($user_agent, $deviceStart, $deviceEnd - $deviceStart); 

// 在浏览器显示信息
if (empty(trim($device))) {
    echo "DEVICE UNKNOWN.";
} else {
    echo $os . "<br>";
    echo $osArr[1] . "<br>";
    echo $device;
}
?>

请问我的代码哪里出错了?

错误分析与修正

核心问题

你的代码在提取设备信息时,完全依赖固定格式的分隔符,没有处理格式异常的情况,导致逻辑失效:

  1. strpos返回false时的逻辑崩溃:比如第二个测试用的User Agent里,$osEnd之后没有下一个;,strpos($user_agent, ";", $osEnd)会返回false,此时$deviceStart = false + 2 = 2,后续strpos找到的是最外层的),最终$device会截取到一大段无效内容,trim后不为空,自然不会触发“DEVICE UNKNOWN”。

  2. 硬编码的分隔符匹配不兼容异常格式:你假设括号内的内容一定是Linux; Android 9 ; SM-577这种三段式结构,但测试用的字符串要么少了设备字段,要么多了多余的分号,手动查找位置的方式根本适配不了这些情况。

修正方案

改用正则表达式提取括号内的内容,再拆分处理,能兼容绝大多数格式异常:

<?php
$user_agent = "Mozilla/5.0 (Linux; Android 9 ; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36";

// 提取括号内的系统与设备信息
if (preg_match('/\((.*?)\)/', $user_agent, $matches)) {
    $innerContent = $matches[1];
    // 按分号拆分,同时自动去除每个字段的首尾空格
    $fields = array_map('trim', explode(';', $innerContent));
    
    $os = $fields[0] ?? '未知操作系统';
    $osVersion = $fields[1] ?? '未知版本';
    $device = $fields[2] ?? '';
    
    if (empty(trim($device))) {
        echo "DEVICE UNKNOWN.";
    } else {
        echo $os . "<br>";
        echo $osVersion . "<br>";
        echo $device;
    }
} else {
    echo "无法解析User Agent";
}
?>

修正说明

  • 用preg_match精准捕获括号内的所有内容,避免手动计算位置的误差;
  • array_map('trim', ...)会自动处理每个字段的前后空格,不管是Android 9 ; 还是Android 9 都能正常拆分;
  • 使用??运算符处理数组下标不存在的情况,防止出现“Undefined array key”错误;
  • 设备字段直接取拆分后的第三个元素,不存在则为空,此时empty(trim($device))会触发预期的提示。

内容的提问来源于stack exchange,提问作者MICHAEL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 22:25:01