Question

This maybe some simple silly thing but I can't figure it out on my own.

I am trying to make a mobile detection script and have had great success. But upon deeper inspection I found that one of my IF clauses seems to be returning TRUE but with the wrong match.

I have this array:

private $arrAgent = array(
    'sony',
    'symbian',
    'nokia',
    'samsung',
    'mobile',
    'windows ce',
    'blackberry',
    'ericsson',
    'danger',
    'palm',
    'series60',
    'palmsource',
    'pocketpc',
    'smartphone',
    'vodafone',
    'iphone',
    'ipad',
    'android'
    );

then I have a function that will loop the array and find if it matches

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;
            }
        }
    }
}

Now the problem is that I found an error in the iPad/iPhone userAgent that prevents from me getting a clear reading.

The iPad user agent looks like this:

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

I got that from a iOS simulator that comes with xCode, on my actual iPad I saw an almost identical user agent, just the OS version and safari version were different.

Now my problem is that in that user agent, the string position returns a match for ipad AND mobile, how can I get it to stop after the first string matched?

Was it helpful?

Solution

It will already stop at the first string in $arrAgent that matches; that's what the break inside the loop is doing.

If you want to prioritize a match against ipad over one against mobile, just rearrange your $arrAgent so 'ipad' appears before 'mobile'.

If you make sure the array is arranged with specific terms at the beginning and generic terms at the end, you'll always get the most specific possible match returned.

OTHER TIPS

I've done a lot of experimentation with this, and the best approach of all the techniques I tried is to use 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];

Why don't you simply first check if it's an iPad?

Something like this:

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;
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top