title: Mobile browser detection with .htaccess fails with Opera Mini
body: <p>I'm having trouble figuring this one out. I'm trying to direct mobile traffic to the mobile version of a website via HTACCESS User-Agent sniffing, like so:</p>
  
  <pre><code>RewriteCond %{HTTP_USER_AGENT} (android|blackberry|ipad|iphone|ipod|iemobile|mini|mobi|palmos|webos|googlebot\-mobile) [NC]
  RewriteCond %{HTTP_HOST} ^mobile\.mywebsite\.com$
  RewriteRule ^([aA0-zZ9\-\/]*)/([^/]*)$ /index.php?page=$1&amp;q=$2&amp;q2=$3&amp;setview=mobile [L,QSA]
  </code></pre>
  
  <p>The string <code>mini|mobi</code> is where the Opera Mini browser should be detected. However, this does NOT happen. I've also changed that string to <code>opera m</code> and other variations. Still no luck.</p>
  
  <p>This rewrite condition appears to work with other mobile browsers, but not Opera, and I don't understand why. Even the second condition, which checks for an explicit pointer to the <code>mobile.</code> subdomain also fails to deliver the mobile content.</p>
  
  <p>I'm not an HTACCESS guru, so my first guess is that my syntax is wrong. But why does this work on other mobile browsers and not Opera Mini?</p>
  
  <p>Thanks for looking!</p>
  
  <hr>
  
  <h2>UPDATE: 2012-06-08</h2>
  
  <p>I actually resorted to a different method by using PHP to check headers. For some reason my HTACCESS file did not detect certain header information. Even though karlcow's answer would validate, I was having trouble getting the iPhone and third-party Android browsers to validate. It wasn't until a page was passed to the PHP interpreter that I was able to read the information. I guess I just don't understand how that works.</p>
  
  <p>Anyway, I borrowed code from an Internet search that I placed into a library function:</p>
  
  <pre><code>function get_device_view() {    
      $view='desktop';
      if(preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone|android)/i', strtolower($_SERVER['HTTP_USER_AGENT'])))
          $view='mobile';
      if((strpos(strtolower($_SERVER['HTTP_ACCEPT']),'application/vnd.wap.xhtml+xml')&gt;0) || ((isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE']))))
          $view='mobile';
      $mobile_ua=strtolower(substr($_SERVER['HTTP_USER_AGENT'],0,4));
      $mobile_agents=array(
          'w3c ','acs-','alav','alca','amoi','audi','avan','benq','bird','blac',
          'blaz','brew','cell','cldc','cmd-','dang','doco','eric','hipt','inno',
          'ipaq','java','jigs','kddi','keji','leno','lg-c','lg-d','lg-g','lge-',
          'maui','maxo','midp','mits','mmef','mobi','mot-','moto','mwbp','nec-',
          'newt','noki','oper','palm','pana','pant','phil','play','port','prox',
          'qwap','sage','sams','sany','sch-','sec-','send','seri','sgh-','shar',
          'sie-','siem','smal','smar','sony','sph-','symb','t-mo','teli','tim-',
          'tosh','tsm-','upg1','upsi','vk-v','voda','wap-','wapa','wapi','wapp',
          'wapr','webc','winw','winw','xda ','xda-');
      if(in_array($mobile_ua,$mobile_agents))
          $view='mobile';
      if (strpos(strtolower($_SERVER['ALL_HTTP']),'OperaMini')&gt;0)
          $view='mobile';
      if(strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'windows')&gt;0)
          $view='desktop';
      return $view;
  }
  </code></pre>
  
  <p>This function is called as part of a strapper process for the website so that before anything is output, the <code>$view</code> is returned so that appropriate pages and stylesheets are loaded.</p>
  
  <p>Additionally, I modified my HTACCESS file to contain the following:</p>
  
  <pre><code>RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{HTTP_COOKIE} !((^|;\s*)DD_VIEW=([^;]+))
  RewriteCond %{HTTP_HOST} mobile\.buffalosbigdeal\.com
  RewriteRule ^([aA0-zZ9\-\/]*)/*([^/]*)$ /index.php?page=$1&amp;q=$2&amp;q2=$3&amp;setview=mobile [L,QSA]
  </code></pre>
  
  <p>As you can see I'm only redirecting explicit calls for the mobile. subdomain, and those not containing a cookie which retains the <code>$view</code> set during the strapper process.</p>
  
  <hr>
  
  <p>My original intent was to perform browser detection exclusively using HTACCESS; because of simplicity and under premise of mod_rewrite's power. But in my frustration, and to meet the deadline, I compromised by settling for a more chunky method that may require more maintenance in the future.</p>
  
  <p><strong>Lesson learned</strong>: Build responsive websites based on browser capabilities (ie: resolution, touch, and DOM level), and do not rely heavily on user-agent strings. Have we yet a solution like this?</p>
  
  <p>Thanks for looking.</p>