HTTP Form With GET method and Apache Rewrite Conditional

Hi all! :slight_smile:

I’ve been trying to resolve this on my own, but I’m really stuck on it, so, I tough you could me help on this…

Ok, I have this HTML form:

File: done.php


<form action="./archive/" method="get">
     <p><input type="text" name="key" /></p>
     <p><input type="submit" value="submit" /></p>
 </form>

And than I have these rules:

File: .htaccess

RewriteEngine On

DirectoryIndex index.php

RewriteRule ^archive(/)?$ done.php [L]

RewriteRule ^([a-z-]+)$ $1.php

RewriteRule ^archive/([a-z0-9]{8})$ done.php?key=$1

I got the pages working fine, so these rules are ok, but what I really want is
that when the user submits the above form to be redirected to http://domain.com/archive/[I][Input Key Here][/I].

At the moment he goes to http://domain.com/archive/?key=[Input Key Here]

The key is a 8 length alphanumeric string.

Can someone please help me on this? :shifty:

Thanks in advance! :wink:

A huge thank for this script.

IB,

NICE signature!

I think that your first RewriteRule will “undo” your third (which is ANDed with the second). What in the world were you trying to do with that mod_rewrite code?

Regards,

DK

Hi dklynn and thank you for your reply!

Ok, so here (almost) my real htacess, my files have a prefix like this -> ;; (eg ;;test.php)

Produce http://domain.com/archive (this is where the form is located)

RewriteRule ^archive(/)?$ ;;done.php [L]

Produce http://domain.com/whatever (basically it removes the php extension and the ‘;;’ prefix from all php files)

RewriteRule ^([a-z-]+)$ ;;$1.php

Produce http://domain.com/archive/abc123 (In this case, there is no form)

RewriteRule ^archive/([a-z0-9]{8})$ ;;done.php?key=$1

That’s what I’m doing, but I just don’t know how to go from
[I]http://domain.com/archive[/I]
to
[I]http://domain.com/archive/abc123[/I]
just using the form I post in my first post and RewriteCond.

Any ideas?

IB,

Your form code will send the submitted code to (in the same directory) archive/{DirectoryIndex}?key=value - this is different than archive/value AND there is nothing to specify that value is of the form ([a-z0-9]{8}). As this is a default browser action, you can’t control this (at least not without capturing the submit event and redirecting from your script).

IMHO, you really need to change “./archive/” to “done.php” and, if you don’t want the value to be seen in a query string, use the POST method instead.

Regards,

DK

Thank you for your reply.

But here is my idea using a different approach:

Forget all the above and what I want is this:

when someone goes to
[I]http://domain.com/archive/?key=abc12345[/I]
I want to redirect to
[I]http://domain.com/archive/abc12345[/I]

Can’t this be done? :confused:

IB,

Yes, of course that can be done - but what script will serve that? I think it’s a matter of semantics but I think you want to accept archive/abc12345 and have it served by archive/{DirectoryIndex}?key=abc12345.

RewriteRule ^/?archive/([a-z]{3}[0-9]{5})$ archive/index.php?key=$1 [L]

Okay, the ^/? is because I don’t know whether you’re using Apache 1.x or Apache 2.x (this will work for both), I don’t like to make Apache guess at the DirectoryIndex file (you should know it and you should use it - it will remain hidden), I took your example literally (three lowercase characters followed by five digits) and you can use your own name for the “key”.

Regards,

DK

Hi dklynn.

I’m running apache 2.

Ok, “archive” is not a directory, it’s a rewrite. And the file is “;;done.php”.

So the “real URL” is http://domain.com/;;done.php?key=123abcde

And it’s rewritten to:
http://domain.com/archive/123abcde

But if the key is not provided, the user goes to http://domain.com/archive/ I[/I] and needs to type his key to access the contents.

So I have the form, with GET method and after the user submits that form he end up in this URL http://domain.com/archive/?key=123abcde I[/I]

So what I’m looking for is a 301 redirect and rewrite conditional that when someone goes to http://domain.com/archive/?key=123abcde (URL after submit the form) it redirects to http://domain.com/archive/123abcde I[/I]

Something like you do with redirect www.domain.com to domain.com. It takes a RewriteCond and does a RewriteRule with a 301 redirect, but applied to my situation.

Thank you in advance and most of all thank you for your patience dklynn.

IB,

Okay, I’m a bit thrown by the use of ;; in the file name AND you, as webmaster, have to create the link to archive/123abcde (mod_rewrite redirects to the “servable” file, ;;done.php with or without the query string).


RewriteRule ^archive/([a-z]{3}[0-9]{5})$ ;;done.php?key=$1 [L]
# OR
# RewriteRule ^archive/([a-z0-9]{8}$ ;;done.php?key=$1 [L]

Remember, though, that the browser will think that it’s in the archive subdirectory so all your relative links will be off a directory level (use the <Base> tag in ;;done.php to correct for that).

301? Add R=301 to the flag list.

Regards,

DK

Ok, that still not what I want, but thank you for your time and patience.

I believe that I need some %{QUERY_STRING} conditional to check if someone is accessing the ?key=123abcde query string and than redirect the user to /archive/123abcde.

:shifty:

IB,

YOU are the webmaster who is generating the links in the way that you want to see them, i.e., archive/123abcde. Unless you have a directory named 123abcde with a DirectoryIndex file, Apache can’t serve that - and you need to create a redirect so that Apache can serve something other than a 404 page. Generally, that’s done (in cases like yours) by parsing the URI and creating a redirection with a query string using the portions of the parsed URI, i.e.

http://www.example.com/archive/123abcde is requested and redirected to

http://www.example.com/done.php?key=123abcde is served.

Regards,

DK

Finally I have found the solution for this!!
It was hard, but I’m very persistent… :slight_smile:

So, if anyone else is interested, the solution was:


RewriteCond &#37;{REQUEST_URI} ^/archive/$
RewriteCond %{QUERY_STRING} ^key=(.*)$
RewriteRule ^(.*)$ /archive/%1? [R=301,L]

Notice the question mark ate the end of RewriteRule? Well, that’s the main “secret”. :wink:

So, my complete htacess goes like this:

RewriteEngine On

DirectoryIndex ;;index.php

RedirectMatch ^/archive$ /archive/

RewriteCond %{REQUEST_URI} ^/archive/$
RewriteCond %{QUERY_STRING} ^key=(.*)$
RewriteRule ^(.*)$ /archive/%1? [R=301,L]

RewriteRule ^archive(/)?$ ;;done.php [L]

RewriteRule ^([a-z-]+)$ ;;$1.php

RewriteRule ^archive/(.*)$ ;;done.php?key=$1

:wink:

And I’ve also changed the form action to action=“./”

Thanks.

IB,

For others, the ? at the end of a redirection will DELETE any pre-existing query string.

Also, ^key=(EVERYTHING or NOTHING)$ merely matches a query string which begins with a key of “key”. It should be key=([^&]+) to capture the value of key at any location in the query string and ONLY the value of key (rather than other keys and their values, too).

MINOR coding “thingie”: WHY capture EVERYTHING then not use it, i.e., RewriteRule ^(.)$ /archive/%1? [R=301,L] discards the $1. The better technique is to use .? rather than ^(.)$ if it’s not going to be used.

Finally, action=“./” is an abuse of the server daemon as it then has to go off looking for the DirectoryIndex. Okay, maybe it does look “prettier” but …

Regards,

Hi dklynn and thank you for the tips!

Here is what I end up with after reading your post:

Options -Indexes

RewriteEngine On

DirectoryIndex ;;index.php

RedirectMatch ^/archive$ /archive/

RewriteCond &#37;{REQUEST_URI} ^/archive/$
RewriteCond %{QUERY_STRING} key=([^&]+)
RewriteRule .? /archive/%1? [R=301,L]

RewriteRule ^archive(/)?$ ;;done.php [L]

RewriteRule ^([a-z-]+)$ ;;$1.php

RewriteRule ^archive/(.*)$ ;;done.php?key=$1 

RewriteRule ^dw/([a-z0-9]{8})/([a-zA-Z0-9/+]*={0,2})$ ;;dw.php?key=$1&dir=$2

The only thing that I’m “not able” to solve right now, is the action=“./”, and I do care a lot about performance, but since I have the DirectoryIndex ;;index.php defined, probably it wont hurt Apache that bad… I don’t know, just a tought.

Once again, thank you very much for the tips :slight_smile:

:tup:

Regards,

DK