homepage Welcome to WebmasterWorld Guest from 23.21.9.44
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
PHP and mod rewrite
arturito




msg:3999883
 12:59 pm on Oct 2, 2009 (gmt 0)

I'm trying to rewrite url for my search page in PHP.

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!

 

jdMorgan




msg:3999895
 1:36 pm on Oct 2, 2009 (gmt 0)

Yes, use two rules, one for each "condition."

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

arturito




msg:4000577
 8:10 pm on Oct 3, 2009 (gmt 0)

Hi 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.

jdMorgan




msg:4000597
 8:32 pm on Oct 3, 2009 (gmt 0)

RewriteConds apply only to the single RewriteRule that follows. So, if the last two rules need to use the query string value, then they also need to have 'copies' of the RewriteCond ahead of them.

I'd also suggest adding a 'virtual start anchor' to that query string pattern:

RewriteCond %{QUERY_STRING} &?s=([^&]+)

This assures that the pattern only accepts exactly "s" as the variable name, and not just anything that ends with "s". That is, if any character precedes "s=", then it must be an ampersand.

Jim

arturito




msg:4000598
 8:39 pm on Oct 3, 2009 (gmt 0)

In that case rules below should be fine?


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 :)

arturito




msg:4000604
 8:47 pm on Oct 3, 2009 (gmt 0)

It doesn't work for me.

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>

jd01




msg:4000623
 9:27 pm on Oct 3, 2009 (gmt 0)

Could you define 'doesn't work' a bit better?

(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.

jdMorgan




msg:4000651
 11:00 pm on Oct 3, 2009 (gmt 0)

Have you got other working rules in this file?

If not, you'll need one or two other directives to enable mod_rewrite and to activate it.

Jim

arturito




msg:4001329
 11:38 am on Oct 5, 2009 (gmt 0)

Sorry I meant your suggestion didn't work.

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

:(

jd01




msg:4001343
 12:02 pm on Oct 5, 2009 (gmt 0)

It's because your rules don't match what you're typing in:

#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.

arturito




msg:4001348
 12:19 pm on Oct 5, 2009 (gmt 0)

If I have these:

#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.

arturito




msg:4001354
 12:30 pm on Oct 5, 2009 (gmt 0)

Sorry, ignore my reply. I misunderstood 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)

jd01




msg:4001355
 12:33 pm on Oct 5, 2009 (gmt 0)

Please print_r($_GET); and dump the array to see what you get when using the second rule and URL.

[edited by: jd01 at 12:36 pm (utc) on Oct. 5, 2009]

arturito




msg:4001357
 12:36 pm on Oct 5, 2009 (gmt 0)

Thanks :-)

jd01




msg:4001359
 12:43 pm on Oct 5, 2009 (gmt 0)

There is nothing wrong with the rule compared to the URL if that's how you have it in your .htaccess... I think you need to look at the php if you are using the last ruleset I gave you.

arturito




msg:4001366
 12:59 pm on Oct 5, 2009 (gmt 0)

Dude! You are a star!Many thanks!
You helped me understand better rewritting rules.

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!

jd01




msg:4001367
 1:01 pm on Oct 5, 2009 (gmt 0)

Glad it worked!

arturito




msg:4001374
 1:09 pm on Oct 5, 2009 (gmt 0)

By the way. Would you recommend changing filename slightly so that visitors cannot access it directly (without rewritting)?

For example

#1
RewriteCond %{QUERY_STRING} &?s=([^&]+)
RewriteRule ^search/$ search-x7s6fedf84gdvc.php?query=%1 [L]

:)

jd01




msg:4001394
 1:30 pm on Oct 5, 2009 (gmt 0)

Actually, I make it so you can't directly access a .php extension directly on my sites for security purposes, which makes it so you don't really need to change the file name you can just use:

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.

arturito




msg:4001396
 1:32 pm on Oct 5, 2009 (gmt 0)

Thanks again!
:)

jdMorgan




msg:4001464
 3:09 pm on Oct 5, 2009 (gmt 0)

Not sure if the code in the above post was accidentally truncated or what, but don't try to take a 'short-cut' on the RewriteCond pattern -- The URL-path part of the pattern for THE_REQUEST should correspond very closely to the RewriteRule pattern if you expect it to work properly.

I'd recommend:

RewriteCond %{THE_REQUEST} ^[A-Z]+\ /search\.php[^\ ]*\ /HTTP
RewriteRule ^search\.php$ - [F]

That is, if the currently-requested URL-path is "/search.php" *and* if "/search.php" is the URL-path originally requested by the client, then return a 403. If the currently-requested URL-path is "/search.php" but the client requested a different URL-path (e.g. the client requested the 'friendly' "/search/2/xyz" path), then don't execute the rule.

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

jd01




msg:4001871
 3:07 am on Oct 6, 2009 (gmt 0)

Actually, no, it was not truncated, because I've had upwards of 50 php files on a website and block any direct request to any of them... It's the code I actually use, because there is no reason anyone ever needs direct access to a php file on my sites... Everything either ends in .html or is extensionless and all are re-written.

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]

jdMorgan




msg:4001876
 3:37 am on Oct 6, 2009 (gmt 0)

What you're calling a subrequest isn't necessarily what Apache terms a subrequest... See the RewriteRule [NS] flag.

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

jd01




msg:4001879
 3:44 am on Oct 6, 2009 (gmt 0)

Actually, Jim I think we were posting / editing at the same time...
ADDED: Yep, we were.

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.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved