PHP - 从 User-Agent 获取准确的 iOS 版本

PHP - Get exact iOS version from User-Agent

我想从 User-Agent 获得 PHP 中的确切 iOS 版本。我很清楚伪造用户代理的可能性,但就我而言,这不是问题。

正常的 iPhone 用户代理字符串如下所示:

Mozilla/5.0 (iPhone; CPU iPhone OS 11_2_1 like Mac OS X) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0 Mobile/15C153 Safari/604.1

如何从中提取 OS 版本?在本例中是“11_2_1”。我必须能够从 iPhone、iPad 和 iPod 用户代理中提取它。它也可以是 X_X 而不是 X_X_X.

到目前为止我得到了这个:

<?php
$version = preg_match('(iPad|iPhone|iphone|iPod).*?(OS |os |OS\_)(\d+
((_|\.)\d)?((_|\.)\d)?)', $_SERVER['HTTP_USER_AGENT']);
echo $version;
?>

但是,从 iPhone 访问它会显示一个空白页面。有人可以帮我吗?

提前致谢。

这应该可以完成工作:

$version = preg_match("/OS ((\d+_?){2,3})/i", $_SERVER['HTTP_USER_AGENT'], $matches);
print_r(str_replace("_",".",$matches[1]));

您可以使用用户代理解析器,甚至创建您自己的解析器。 Here you have an example, Also I found this php project PhpUserAgent,使用起来应该很简单:

$result = parse_user_agent($ua);

然后您可以从该对象中提取 version

这个 user-agent-parser 对于 javascript 也很有效。

尝试使用这个:"/(i(?:phone|pad|pod)) OS (\d+_\d+_\d+)/i"

代码

您可以执行多个正则表达式来获取 OS 版本。下面的正则表达式可能是最快的:

See regex in use here

ip(?:hone|[ao]d) os \K[\d_]+

注意:这些正则表达式都使用了i标志。

也可以使用其他变体,例如:

i(?:phone|pad|pod) os \K[\d_]+
i(?:phone|pad|pod) os ([\d_]+)

用法

See code in use here

<?php

$re = '/ip(?:hone|[ao]d) os \K[\d_]+/i';
$str = 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_2_1 like Mac OS X) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0 Mobile/15C153 Safari/604.1';
preg_match($re, $str, $matches, PREG_OFFSET_CAPTURE, 0);
var_dump($matches);

注意:要分隔结果中的每个版本部分,您可以使用以下行 as shown here:

var_dump(explode("_", $matches[0][0]));

用法 - 使用 OP 代码

<?php

$re = '/ip(?:hone|[ao]d) os \K[\d_]+/i';
preg_match($re, $_SERVER['HTTP_USER_AGENT'], $matches, PREG_OFFSET_CAPTURE, 0);
var_dump($matches);

结果

输入

Mozilla/5.0 (iPhone; CPU iPhone OS 11_2_1 like Mac OS X) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0 Mobile/15C153 Safari/604.1

输出

输出匹配:

11_2_1

_ 上输出与 explode() 的匹配(见第一个 Usage 部分的注释):

11
2
1

说明

  • ip字面匹配
  • (?:hone|[ao]d) 匹配以下任意一项
    • hone 字面匹配(使 iphone
    • [ao]d 匹配 ao 后跟 d(生成 ipadipod
  • </code> 匹配文字 space 个字符</li> <li><code>os字面匹配
  • </code> 匹配文字 space 字符。我注意到 OP 也有 <code>OS\_,这让我觉得这里可能有下划线字符。如果是这样的话this can be changed to [ _] instead.
  • \K 重置比赛的起点。任何先前消耗的字符都被排除在最终匹配之外
  • [\d_]+ 匹配一个或多个任意数字或下划线字符