Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

htaccess how to access/get search parameters after a url rewrite

I have a htaccess rewrite rule, based upon a form being submitted. I am trying to read the search parameters, this is a simple example of keyword search, but ideally more parameters eventually will be added:

single parameter url: //thesite.com/search?keyword=sample+text

2 parameter url: //thesite.com/search?keyword=sample+text&location=myCity

In my htacess I have a simple Rewrite rule looking for the search like so:

RewriteRule ^.*search?(.*)$ /displayPage.php?page=search&options=$1

I access the options parameter like so:

$searchOptions = filter_input(INPUT_GET, "options")!==NULL?filter_input(INPUT_GET, "options"):'';

when I output this variable it's has nothing.

I tried var_dump($_GET) and the result was:

array (size=2)
  'page' => string 'search' (length=6)
  'options' => string '' (length=0)

The html used to generate the url:

<form class="start-search" action="/search" method="get">
  <input id='keyword' name='keyword' class="search-str" type="text" value="" placeholder="Start Your Search">
  <!-- Meant to hold value for category -->
  <input class="search-cat" type="hidden" value="" placeholder="Start Your Search">

  <button class="btn" type="submit">
    <i class="fa fa-arrow-circle-o-right"></i>
  </button>
</form>

I was expecting the $searchOptions to contain the following:

for single parameter: keyword=sample+text

for more than one parameter: keyword=sample+text&location=myCity

I could than split the string based upon & and = and replace + with a whitespace.

Any ideas why the the parameters are not being included?

Thank you so very much

UPDATE: Applying Case 1

RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^search?(.*)/$ displayPage.php?page=search&%1

My apache log reports the following:

"GET /search?keyword=test+text HTTP/1.1" 404 286

What is incorrect? I tried removing the ? from the rewrite rule, I replaced it with a / as the sample provided. I modified the html to include a / after it. When I did the following was reported in apache logs:

"GET /search/?keyword=test+text HTTP/1.1" 301 329
"GET /search?keyword=test+text HTTP/1.1" 404 286

ADDITIONAL HTACCESS INFO

I have the following already applied

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

I have a bunch of other RewriteRule for other urls that are all functional. This is my first query string one which has me stumped.

Update2

Trying Steve E. [QSA]

RewriteRule ^.*search?(.*)/$ displayPage.php?page=search&%1 [QSA]

Apache log reports

 "GET /search?keyword=sample+search HTTP/1.1" 404 286

Solution: as provided by Steve E with one fix from above, forgot the / before the call to displayPage.php. It works for single and multiple parameters. :)

RewriteRule ^.*search?(.*)/$ /displayPage.php?page=search&%1 [QSA]
like image 279
mcv Avatar asked Oct 09 '15 11:10

mcv


2 Answers

Use the [QSA] flag on your RewriteRule

RewriteRule ^search?(.*)/$ displayPage.php?page=search&%1 [QSA]

Here is the docs

Modifying the Query String By default, the query string is passed through unchanged. You can, however, create URLs in the substitution string containing a query string part. Simply use a question mark inside the substitution string to indicate that the following text should be re-injected into the query string. When you want to erase an existing query string, end the substitution string with just a question mark. To combine new and old query strings, use the [QSA] flag.

like image 64
Steve E. Avatar answered Sep 22 '22 03:09

Steve E.


Use RewriteCond We were used to use RewriteRule to match a URL, and then rewrite it. However, RewriteRule will always ignore your query string (GET data) so we need to use RewriteCond to capture the values in the query string.

This is the syntax:

RewriteCond %{QUERY_STRING} ^(.*)$
  • %{QUERY_STRING} captures the matched query string into % variable.
  • %1 will carry the matched content of the first group of brackets. The second part ^(.*)$ is the pattern you want to match.
  • ^ means “start with”
  • $ means “end”
  • Like regular expressions, the dot in (.*) matches any characters.
  • The asterisk * inside the brackets is a quantifier that match 0 occurrence to infinite occurrences.

    Therefore, combining them, (.*) matches any characters So, clearly, in this example, it matches the whole query string part. Some common ways of capturing query strings

Case 1

This case is for you if you’ve rewritten your URL this way, for example: FROM site.com/show.php?id=seo TO site.com/show/seo/

And you WANT to pass or append some GET data using the rewritten URL, like: site.com/show/seo/?lang=en&source=firefox you want it to append like site.com/show.php?id=seo&lang=en&source=firefox

This is the htaccess rules:

RewriteEngine On
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^show/(.*)/$ show.php?id=$1&%1

This RewriteCond captures whole query string (first bracket) into %1 In this case, the captured string %1 is “lang=en&source=firefox” We then do our normal URL rewriting and append the %1 to the URL after a ampersand (&).

Case 2

This case is for you if you know specifically or want to control what query string you are going to use.

For example, you only want to match lang=xxx and NOTHING ELSE, for example: site.com/show/seo/?lang=en&more=1 you want it to append like site.com/show.php?id=seo&lang=en, ignoring other unknown query string.

RewriteEngine On
RewriteCond %{QUERY_STRING} ^lang=(\w+)$
RewriteRule ^show/(.*)/$ show.php?id=$1&lang=%1
  • This RewriteCond captures lang‘s GET data (first bracket) into %1,
  • \w matches word characters
  • The plus + means one occurrence or more
  • In this case, the captured string %1 is “en”

Case 3

Similar as Case 2, but this case we have more queries to match.

For example, you only want to match lang=xxx and time=000, for example: site.com/show/seo/?lang=en&time=100 you want it to append like site.com/show.php?id=seo&lang=en&time=100

RewriteEngine On
RewriteCond %{QUERY_STRING} ^lang=(\w+)&time=(\d+)$
RewriteRule ^show/(.*)/$ show.php?id=$1&lang=%1&time=%2
  • This RewriteCond captures lang's GET data (first bracket) into %1
  • This RewriteCond also captures time‘s GET data (second bracket) into %2
  • \w matches word characters
  • \d matches decimals
  • The plus + means one occurrence or more

In this case, the captured string %1 is “en” , %2 is "100".

Useful Link to Apache mod rewrite

like image 21
Dheeraj Nayak Avatar answered Sep 18 '22 03:09

Dheeraj Nayak