在PHP中使用strpos()匹配的第一个字符串处停止


stop at the first string matched using strpos() in PHP

这可能是一些简单而愚蠢的事情,但我自己无法解决。

我正在尝试制作一个移动检测脚本,并取得了巨大成功。但经过更深入的检查,我发现我的一个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版本不同。

现在我的问题是,在该用户代理中,字符串位置返回ipadmobile的匹配项,如何在第一个字符串匹配后使其停止?

我对此做了很多实验,在我尝试的所有技术中,最好的方法是使用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;
        }
    }
}