Wednesday, April 6, 2011

Apache rewrite_mod: RewriteRule path and query string

I currently have a website with a standard web interface on index.php, and I made an iPhone-friendly version in iphone.php.
Both pages handle the same arguments.

It works fine when I manually go to .../iphone.php, but I'd like to rewrite anything on .../path/ and .../path/index.php to iphone.php if %{HTTP_USER_AGENT} contains mobile, and optionally add the query string (not sure if/when I'd need to add it).

So far, this is what I have in my .../path/.htaccess:

RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^.+mobile.+$ [NC]
RewriteRule index.php?(.*) iphone.php?$1 [L]
RewriteRule index.php      iphone.php [L]

The problems are, it matches index.php in any subfolder, and it won't match .../path/?args

From stackoverflow
  • How about

    RewriteEngine On
    RewriteCond %{HTTP_USER_AGENT} ^.*mobile.*$ [NC]
    RewriteRule /path/index.php /path/iphone.php [QSA,L]
    

    EDIT: QSA is Query string append, so you don't need to handle that differently. If you want you can add an extra parameter too, like:

    RewriteRule /path/index.php /path/iphone.php?extra=param [QSA,L]
    
    1. RewriteCond is applied to exactly one rewrite rule.
    2. To match all user agents containing 'mobile' in it's name .* - 0 or more any character should be used in ^.+mobile.+$ statement.
    3. RewriteRule by default doesn't include query string - [QSA] flag should be used to include query string.
    4. RewriteRule uses regexp - you should use \. to escape dots.
    5. RewriteRule automatically saves query string the same, if not specified another.

    UPDATED:

    Complete .htacess:

    RewriteEngine On
    
    RewriteCond %{HTTP_USER_AGENT} ^.*mobile.*$ [NC]
    RewriteRule ^(.*)index\.php $1iphone.php [L]
    
    RewriteCond %{HTTP_USER_AGENT} ^.*mobile.*$ [NC]
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteRule ^(.*)$ $1iphone.php [L]
    
    1ace : Thanks a lot for all those clarifications, but this does not resolve my main concern: `.../path/?args` is still not handled…
    SergeanT : I've added possible fix of this problem. Do you need to rewrite `.../path?args` (without trailing slash) too?
    1ace : I did try that, but Apache returns a 500 when I do. My guess is `^(.*)$` goes in some kind of a loop, and never gets out.
    SergeanT : You're right. I've added `RewriteCond %{REQUEST_URI} !^.*iphone\.php.*` to prevent loop. It's strange to me that `[L]` seems not work.
    1ace : For a second here, I thought you had _the_ solution... It does help with the `/?` problem, but any other requested URI (like, say, my `style.css`) now returns a 404 :( There has to be some way to match `.../?` without matching everything... The only option I see is to counter-match every request URI I still need to let through
    SergeanT : To prevent rewriting existing files I've added `RewriteCond %{REQUEST_FILENAME} !-f` (sounds like not existings file) for `^(.*)$` rewrite rule.
    1ace : It works ! Thank you very much, you saved me quite a lot of tries and testings :)
    1ace : Actually, we don't need `RewriteCond %{REQUEST_URI} !^.*iphone\.php` anymore, as it's taken care of by `RewriteCond %{REQUEST_FILENAME} !-f` and `iphone.php` has to be a file for the whole thing to work.

0 comments:

Post a Comment