I'm working on a website project, www.experimonkey.com. In the root directory, I have directories for experiments, games, etc., that I've been serving dynamically with php. I want to clean up the URLs so that instead of /experiments?eid=homemade-lava-lamp, for example, a user can go to /experiments/homemade-lava-lamp. I'd also like to have a redirect so that if a user goes to the old link, /experiments?eid=homemade-lava-lamp, they will be redirected to the clean link.
I thought I had figured out the first part of the problem with the following code in /experiments/.htaccess:
RewriteEngine On
RewriteRule ^([a-zA-Z0-9\-]+)/?$ index.php?eid=$1 [L]
This works for the dynamic pages; however, I later realized that this would screw up the other, real directories in the /experiments folder. For example, the address /experiments/submit (which is actually /experiments/submit/index.php) redirects to /experiments/submit?eid=submit--why, I have no idea.
But also, no matter what combinations of the following code I tried (and all of the other threads and documentation I've read), I could not get the old URL to redirect to the clean URL:
RewriteCond %{QUERY_STRING} eid=(.+)
RewriteRule .+ https://www.experimonkey.com/experiments/%1 [R=301]
RewriteEngine On
I've worked it out this far. Everything is now mostly working, except the last two parts create an infinite loop and I'm not sure how to fix it.
#Ignore existing directories and files unless has query string
RewriteCond %{QUERY_STRING} !eid=(.*)
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
#Redirect and remove query string
RewriteCond %{QUERY_STRING} /?eid=(.*)
RewriteRule (.*) https://www.experimonkey.com/experiments/%1? [R=301,L]
#Rewrite internally to actual URL
RewriteRule ^([a-zA-Z0-9\-]+)/?$ index.php?eid=$1 [L]
I finally figured it out--I hope this can help someone somewhere along the way (I honestly can't believe how long this took me to figure out).
#Ignore existing directories and files unless has query string
RewriteCond %{QUERY_STRING} !eid=(.*)
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
#Redirect and remove query string.
#First line was the crucial condition to stop loop by checking for internal redirect first.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} /?eid=(.*)
RewriteRule (.*) https://www.experimonkey.com/experiments/%1? [R=301,L]
#Rewrite internally to actual URL
RewriteRule ^([a-zA-Z0-9\-]+)/?$ index.php?eid=$1 [L]