Forum Moderators: phranque
I would like to rewrite for these conditions:
1)
mydomain.com/searchdb.php?query=john
to
mydomain.com/search/s?=john
2)
mydomain.com/searchdb.php?query=john&pageno=2
to
mydomain.com/search/2/s?=john
3)
mydomain.com/searchdb.php?query=john&pageno=2&sort_order=date
to
mydomain.com/search/2/date/s?=john
or anyone has a better idea? :-)
"john" is a word entered in the search box form with method GET
That's what I came up with so far:
RewriteCond %{QUERY_STRING} s=(.*)
RewriteRule ^search/(.*) search.php?query=%1
that works for condition 1
this however:
RewriteCond %{QUERY_STRING} s=(.*)
RewriteRule ^search/([0-9])/(.*) search.php?query=%1&pageno=$1
works for the condition no. 2 but doesnt work for codition no. 1 anymore.
Anyone has any idea how to get all conditions working?
Thanks in advance!
Do not use the "(.*)" pattern in your RewriteRules unless you really want to match "everything, anything, or nothing." Your use of that ambiguous pattern in both of your rules and leaving your patterns un-anchored ensures that whichever rule you put first, the other rule will never execute. I suggest using "([^/]+)$" in the RewriteRules and "([^&]+)" in the RewriteConds instead.
If you're not sure of the meanings of these suggested patterns, see the regular-expressions tutorial cited in our Apache Forum Charter (the Charter link is at the top left of this page).
Also, always use an [L] flag on your rules, unless you know specifically why you don't want to use it.
Jim
Thanks for your reply! I'm now very familiar with RewriteRules but I applied your suggestions to my .htaccess
RewriteCond %{QUERY_STRING} s=([^&]+)
RewriteRule ^search/([^/]+)$ search.php?query=%1
RewriteRule ^search/([0-9])/([^/]+)$ search.php?query=%1&pageno=$1
RewriteRule ^search/([0-9])/(date地z屹a)/([^/]+)$ search.php?query=%1&pageno=$1&sort_order=$2
But this doesn't seem to be working. I know I'm missing something here but cannot figure out what it is.
I'd also suggest adding a 'virtual start anchor' to that query string pattern:
RewriteCond %{QUERY_STRING} &?s=([^&]+)
Jim
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([^/]+)$ search.php?query=%1
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/([^/]+)$ search.php?query=%1&pageno=$1
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/(date地z屹a)/([^/]+)$ search.php?query=%1&pageno=$1&sort_order=$2
I'm going to test it now :)
I've tried also only with that bit (fault finding)
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([^/]+)$ search.php?query=%1
maybe there is an error in my form (although I dont think so) which goes like that:
<form id="searchform" method="get" action="http://mydomain.com/search/">
<fieldset class="searchbox">
<input name="s" id="s" class="s" type="text" />
<button class="button-search" title="Search" type="submit">Search</button>
</fieldset>
</form>
(I personally think it's more likely the .php search page than the form. Have you tried echo $_GET['s']; at the top of your .php page receiving the form data to see if the information is being passed and received yet?)
ADDED: Make sure you get an [L] flag on all of your rules, and I would use a server relative URL on the right side. (It also looks like your rules will not match, because your URLs ends in a /, so you need to add it to the left side of your rule.)
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([^/]+)/$ /search.php?query=%1 [L]
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/([^/]+)/$ /search.php?query=%1&pageno=$1 [L]
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/(date地z屹a)/([^/]+)/$ /search.php?query=%1&pageno=$1&sort_order=$2 [L]
ADDED x 2: Make sure if you copy and paste you change the ¦ (broken bar) to an actual bar character or you will have a server error... The forum software changes a regular bar to a broken bar.
I'm echoing $_GET['s'] well I'm echoing $_GET['query'] as 's' is being rewritten to 'query'.
I also think that I don't need forward slash before search.php since my htaccess defines RewriteBase.
All other rules are working fine.
This is my htaccess:
RewriteEngine On
RewriteBase /
RewriteRule ^article/a([0-9]+)//?$ article.php?id=$1 [L]
RewriteRule ^profile/p([0-9]+)//?$ p.php?id=$1 [L]
RewriteRule ^autosearch//?$ quicksearch.php?$ [L]
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([^/]+)$ search.php?query=%1 [L]
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/([^/]+)$ search.php?query=%1&pageno=$1 [L]
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/(date地z屹a)/([^/]+)$ search.php?query=%1&pageno=$1&sort_order=$2 [L]
ErrorDocument 404 [mydomain.com...]
changing it to
#1
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([^/]+)/$ /search.php?query=%1 [L]
#2
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/([^/]+)/$ /search.php?query=%1&pageno=$1 [L]
#3
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/(date地z屹a)/([^/]+)/$ /search.php?query=%1&pageno=$1&sort_order=$2 [L]
didn't help either. In both cases as I enter urls:
[mydomain.com...] #I get my error.php
[mydomain.com...] # echo $_GET['query'] returns 'john', $_GET['pageno'] returns nothing
[mydomain.com...] # echo $_GET['query'] returns 'john', $_GET['sort_order'] and $_GET['pageno'] returns nothing
:(
#1
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([^/]+)/$ /search.php?query=%1 [L]#2
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/([^/]+)/$ /search.php?query=%1&pageno=$1 [L]#3
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/(date地z屹a)/([^/]+)/$ /search.php?query=%1&pageno=$1&sort_order=$2 [L]didn't help either. In both cases as I enter urls:
http://example.com/search/?s=john #I get my error.php
http://example.com/search/5/?s=john # echo $_GET['query'] returns 'john', $_GET['pageno'] returns nothing
http://example.com/search/5/date/?s=john # echo $_GET['query'] returns 'john', $_GET['sort_order'] and $_GET['pageno'] returns nothing
See the ([^/]+)/ at the end of the rules? They don't match, because there is no other directory...
#1
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/$ search.php?query=%1 [L]
#2
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/$ search.php?query=%1&pageno=$1 [L]
#3
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/(date地z屹a)/$ search.php?query=%1&pageno=$1&sort_order=$2 [L]
Try the preceding... You are correct, you do not need the preceding / on the right side, but to match correctly, since the URLs you want to rewrite end in a / you will need the / at the end of the left side.
Please make sure you empty your browser cache before testing.
#1
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/$ search.php?query=%1 [L]
#2
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])$ search.php?query=%1&pageno=$1 [L]
#3
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/(date地z屹a)$ search.php?query=%1&pageno=$1&sort_order=$2 [L]
calling
[mydomain.com...]
[mydomain.com...]
[mydomain.com...]
should work but it doesnt :(
I wouldn't like to add "/" in the end such as
[mydomain.com...] as
"john" is received from the form post using GET and I don't really know how to add "/" in the end when posting it.
First rule does the job.
Problems with second one.
#2
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/$ search.php?query=%1&pageno=$1 [L]
[mydomain.com...]
does not echo pageno (does echo query)
End result for anyone who is having similar problem:
RewriteEngine On
RewriteBase /
#1
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/$ search.php?query=%1 [L]
#2
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/$ search.php?query=%1&page_no=$1 [L]
#3
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/([0-9])/(date地z屹a)/$ search.php?query=%1&page_no=$1&sort_order=$2 [L]
[mydomain.com...] # results for "john"
[mydomain.com...] # second page of results for "john"
[mydomain.com...] # second page of results for "john" sorted alphabetically.
Much appreciated Jim!
RewriteCond %{THE_REQUEST} ^.
RewriteRule \.php$ - [F]
Be careful before installing though... If you need people to be able to visit a URL with .php in it, they will not be able to.
I'd recommend:
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /search\.php[^\ ]*\ /HTTP
RewriteRule ^search\.php$ - [F]
The purpose of testing THE_REQUEST is to differentiate between direct clients requests for /search.php (forbidden), and client requests for URL-paths such as /search/2/xyz which were internally-rewritten to /search.php (allowed).
Jim
It checks any .php request and then simply checks to see if it is an original request or internal-subrequest. If it's original I know you are venturing somewhere you should not be and block the access. I only need to know if the request is original or secondary (internal subrequest) to know what to do, so I don't need to worry too much about the method of the request or the exact file name if it ends in .php, all I need to know is 'original' or 'sub' request.
It's why I posted the caution on using it...
It blocks everything, except subrequests.
Acutally in looking closer, maybe I copied and pasted an older version of the code...
This is the most recent and works for sure:
RewriteCond %{THE_REQUEST} \.php
RewriteRule \.php$ - [G]
If the URL-path matched by RewriteRule is 'search.php', then it could be being requested in one of two ways: It could be a direct client request for '/search.php' that we *do not* want to allow, in which case THE_REQUEST will also contain '/search.php', or it could have been a client request for '/search/<term>/' which was just-previously rewritten (within this same HTTP transaction's context) to '/search.php' which we *do* want to allow, in which case THE_REQUEST will contain '/search/<term>/.
But in neither case will THE_REQUEST be blank. In fact, even if the URL-path itself is blank, you'd still have an HTTP method (e.g. GET) and a protocol (e.g. HTTP/1.0) in THE_REQUEST. That's because THE_REQUEST is a copy of the HTTP Request line received from the client --the HTTP request that invoked this instance of the server-- and is not changed by any of the server's request processing, because it 'belongs' to the client and is not a representation of an internally-generated server variable.
So this may work for you, but if so, it's not working in the same way that is usually intended when we check to see if the client requested the same URL-path as that being examined by RewriteRule.
So given the above, how does your application of THE_REQUEST differ in its goals, and under what circumstances do you find it to be blank?
[added] It appears that you've edited your post, so this post may no longer make sense in the direct context of the thread (RewriteCond testing THE_REQUEST for "\.php" rather than "^." as previously posted). I'll try to sort it out later... [/added]
Jim
I posted a different variation of the code above, because I copied / pasted incorrectly before.
My apologies to you and the OP for the confusion.
I do check THE_REQUEST to see if it contains .php which it should not at any time on any of my sites, except in my own personal test directory.
Again, my apologies for posting the wrong code...
I opened the wrong (it's old + not working) .htaccess file for the answer.