остановка на первой строке с использованием strpos () в PHP - PullRequest
0 голосов
/ 15 января 2012

Это может быть какая-то простая глупость, но я не могу понять это самостоятельно.

Я пытаюсь создать сценарий мобильного обнаружения и добился большого успеха. Но при более глубоком рассмотрении я обнаружил, что одно из моих 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

Я получил это из симулятора iOS, который поставляется с xCode, на моем реальном iPad я увидел почти идентичный пользовательский агент, только версия ОС и версия safari были разными.

Теперь моя проблема в том, что в этом пользовательском агенте позиция строки возвращает совпадение для ipad И mobile, как я могу остановить его после сопоставления первой строки?

Ответы [ 3 ]

2 голосов
/ 15 января 2012

Я много экспериментировал с этим, и лучший подход из всех техник, которые я пробовал, это использовать регулярное выражение:

$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];
0 голосов
/ 15 января 2012

Он уже остановится на первой строке в $arrAgent, которая соответствует;это то, что делает break внутри цикла.

Если вы хотите расставить приоритеты для совпадения с ipad, а не для mobile, просто переставьте $arrAgent, чтобы 'ipad' отображалось до 'mobile'.

Если вы убедитесь, что массив организован с определенными терминами в начале и общими терминами в конце, вы всегда получите наиболее конкретное возвращаемое совпадение.

0 голосов
/ 15 января 2012

Почему бы вам просто не проверить сначала, является ли это 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;
        }
    }
}
...