24

I am looking to rewrite urls with multiple substrings. One substring is being requested as a subdirectory, while any others are requested as normal query string parameters.

For example, I would like to rewrite urls from

http://www.mysite.com/mark/friends?page=2

to

http://www.mysite.com/friends.php?user=mark&page=2

I am able to accomplish this with the exception of the question mark character. Here is my rewrite rule:

...
RewriteEngine On
RewriteBase /
RewriteRule ^([A-Za-z0-9-_]+)/friends[?]?([^/\.]+)?$ friends.php?user=$1&$2 [L]

If I change the question mark to any other character it works great. It seems like the problem is that the '?' character is being interpreted incorrectly as the start of a new query string.

I need to pass on any parameters that appear after /user/friends as is. How do I accomplish this?

markb
  • 3,451
  • 5
  • 24
  • 25

3 Answers3

36

You should be using the [QSA] flag instead of trying to rewrite the query string. [QSA] passes on the query string to the rewritten URL.

So your rule should look like:

...
RewriteEngine On
RewriteBase /
RewriteRule ^([A-Za-z0-9-_]+)/friends/? friends.php?user=$1 [QSA,L]

Your case is very similar to the example given for using the QSA flag in the mod_rewrite cookbook.

TheKarateKid
  • 772
  • 11
  • 19
Chad Birch
  • 73,098
  • 23
  • 151
  • 149
  • Thanks for the answer. Works really well & I'm reading the cookbook right now. – markb May 05 '09 at 12:56
  • Supers solution it worked for me too, though I edited code to my conditions: RewriteRule ^([A-Za-z0-9-_]+)\.php? pindex.php?typeofpage=$1 [QSA,L] – Hovhannes Babayan Jul 11 '16 at 14:23
13

The query is not part of the URL path and thus cannot be processed with the RewriteRule directive. This can only be done with the RewriteCond directive (see %{QUERY_STRING}).

But as Chad Birch already said it suffices th set the QSA flag to automatically get the original requested query appended to the new URL.

Community
  • 1
  • 1
Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • QSA has a problem listed at https://stackoverflow.com/questions/16468098/what-is-l-in-qsa-l-in-htaccess/16468677#comment79837245_16468677. Also, rewritecond query_string is not able to distinguish requests with no query strings, vs requests with naked query strings (ie a single question mark and nothing else). Is there a way to distinguish these two requests? – Pacerier Sep 27 '17 at 06:20
  • Ok nbm.. I've found it: `${the_request}` – Pacerier Sep 27 '17 at 07:43
2

In addition to using the rewrite flag QSA, you can also use the QUERY_STRING environment variable as shown below:

RewriteEngine On
RewriteBase /
RewriteRule ^([A-Za-z0-9-_]+)/friends$ /friends.php?user=$1&%{QUERY_STRING}

And the URL in question

http://www.example.com/mark/friends?page=2

will be rewritten to (as specified):

http://www.example.com/friends.php?user=mark&page=2
Yuci
  • 27,235
  • 10
  • 114
  • 113