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]
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.
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”(.*)
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
%1
, \w
matches word characters+
means one occurrence or more%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
%1
%2
\w
matches word characters\d
matches decimals+
means one occurrence or moreIn this case, the captured string %1
is “en” , %2
is "100".
Useful Link to Apache mod rewrite
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With