这可能是一些简单而愚蠢的事情,但我自己无法解决。
我正在尝试制作一个移动检测脚本,并取得了巨大成功。但经过更深入的检查,我发现我的一个IF
子句似乎返回了TRUE
,但匹配错误。
我有这个阵列:
private $arrAgent = array(
'sony',
'symbian',
'nokia',
'samsung',
'mobile',
'windows ce',
'blackberry',
'ericsson',
'danger',
'palm',
'series60',
'palmsource',
'pocketpc',
'smartphone',
'vodafone',
'iphone',
'ipad',
'android'
);
然后我有一个函数,它将循环数组并查找它是否与匹配
private function detectMobileAgent() {
if ($this->MobileDevice === false) {
foreach ($this->arrAgent as $key => $value) {
if (strpos(Server::userAgent(), $value) !== false) {
$this->MobileDevice = true;
// echo $value;
break;
}
}
}
}
现在的问题是,我在iPad/iPhone用户代理中发现了一个错误,使我无法获得清晰的读数。
iPad用户代理看起来像这样:
mozilla/5.0 (ipad; u; cpu os 4_3_2 like mac os x; en-us) applewebkit/533.17.9 (khtml, like gecko) version/5.0.2 mobile/8h7 safari/6533.18.5
我从xCode附带的iOS模拟器中得到了这一点,在我实际的iPad上,我看到了一个几乎相同的用户代理,只是操作系统版本和safari版本不同。
现在我的问题是,在该用户代理中,字符串位置返回ipad
和mobile
的匹配项,如何在第一个字符串匹配后使其停止?
我对此做了很多实验,在我尝试的所有技术中,最好的方法是使用regex:
$arrAgent = array(
'sony',
'symbian',
'nokia',
'samsung',
'mobile',
'windows ce',
'blackberry',
'ericsson',
'danger',
'palm',
'series60',
'palmsource',
'pocketpc',
'smartphone',
'vodafone',
'iphone',
'android',
'ipad'
);
$agent = 'mozilla/5.0 (ipad; u; cpu os 4_3_2 like mac os x; en-us) applewebkit/533.17.9 (khtml, like gecko) version/5.0.2 mobile/8h7 safari/6533.18.5';
$pattern = '/((' . implode(')|(', $arrAgent) . '))/';
$found = preg_match($pattern, $agent, $matches);
if (!$found) {
print 'not a mobile device';
exit;
}
print 'device: ' . $matches[0];
它将停止在$arrAgent
中第一个匹配的字符串处;这就是循环中的break
正在做的事情。
如果你想优先考虑与ipad
的比赛,而不是与mobile
的比赛,只需重新排列你的$arrAgent
,使'ipad'
出现在'mobile'
之前。
如果您确保数组的开头是特定术语,末尾是通用术语,那么您总是会得到最具体的匹配结果。
为什么不先检查一下它是否是iPad?
类似这样的东西:
if ($this->MobileDevice === false && strpos(Server::userAgent(), 'ipad') === false) {
foreach ($this->arrAgent as $key => $value) {
if (strpos(Server::userAgent(), $value) !== false) {
$this->MobileDevice = true;
// echo $value;
break;
}
}
}