Chris Tonkinson Chris Tonkinson - 2 months ago 16
PHP Question

mod_rewrite with question marks and ampersands (with PHP)

I have a PHP-based web app that I'm trying to apply Apache's mod_rewrite to.

Original URLs are of the form:

http://example.com/index.php?page=home&x=5

And I'd like to transform these into:

http://example.com/home?x=5

Note that while rewriting the page name, I'm also effectively "moving" the question mark. When I try to do this, Apache happily performs this translation:

RewriteRule ^/([a-z]+)\?(.+)$ /index.php?page=$1&$2 [NC,L]


But it messes up the
$_GET
variables in PHP. For example, a call to
http://example.com/home?x=88
yields only one
$_GET
variable (
page => home
). Where did
x => 88
go? However, when I change my rule to use an ampersand rather than a question mark:

RewriteRule ^/([a-z]+)&(.+)$ /index.php?page=$1&$2 [NC,L]


a call like
http://example.com/home&x=88
will work just as I'd expect it to (i.e. both the
page
and
x
$_GET variables are set appropriately).

The difference is minimal I know, but I'd like my URL variables to "start" with a question mark, if it's possible. I'm sure this reflects my own misunderstanding of how mod_rewrite redirects interact with PHP, but it seems like I should be able to do this (one way or another).

Thanks in advance!

Cheers,

-Chris

Answer

Try this:.

RewriteCond %{REQUEST_URI} !^/index.php
RewriteRule ^/([a-z]+)(?:$|\?(?:.+)) /index.php?page=$1 [NC,L,B,QSA,NE]

B escapes the backreference (shouldn't be necessary since it is matching [a-z]+, but in case you want to extend it later, it might be useful).

EDIT: added RewriteCond. EDIT 2: QSA takes care of adding the ampersand.