UPDATE: Solution at bottom.
I recently switched from using a set up such as index.php?p=page_name&o=temporary_override and switched to clean urls such as /page_name/temporary_override. The temporary override is just so I can see the results of the site changes while it’s being built.
I currently have mod_rewrite set to:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]
Which will capture the “subdirectories” and then PHP parses the URL from the GHPAGE $_GET var. What I want is to set up a 301 redirect so that anyone using index.php?p=something&o=something_else will get redirected to /something/something_else. Any idea how I can accomplish this? The p & o may come in any order and one or the other may not exist.
EDIT: Ok, after help from @Jon-Lin, @dambrisco, and @anubhava, I have gotten closer. My .htaccess file now looks like:
RewriteEngine On
#Base Directory
RewriteBase /test/
#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^index\.php$ /%4/%5 [R=301,L]
#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^index\.php$ /%4 [R=301,L]
#Remove index.php
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*index\.php\ HTTP\/
RewriteRule ^index\.php$ / [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]
It is now redirecting, but not quite where it needs to go. root/test/index.php?p=test&o=override now redirects to root/test/override?p=test&o=override. Closer, but I can’t figure out how to get rid of the GET vars which are being added to the URL or why it’s redirecting to the root directory instead of to the RewriteBase directory.
EDIT:
It’s now redirecting properly, but for some reason it’s dropping the /test/ RewriteBase folder from the equation. http://www.domain.com/test/index.php?p=page1&o=operation is getting redirected to http://www.domain.com/page1/operation. New .htaccess file is below:
RewriteEngine On
RewriteBase /test/
#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^ /%4/%5? [R=301,L]
#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^ /%4? [R=301,L]
#if index.php
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*index\.php\ HTTP\/
RewriteRule ^index\.php$ /$ [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]
Thanks everyone. Question has been solved. Final .htaccess is below for reference.
RewriteEngine On
RewriteBase /test/
#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^ %4/%5? [R=301,L]
#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^ %4? [R=301,L]
#if index.php
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*index\.php\ HTTP\/
RewriteRule ^index\.php$ ? [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]
Add this somewhere in your htaccess:
And if you want to cover the case where there’s no “temporary_override”, add this too:
Add a
?at the end of/%4/%5to get rid of the query string. And remove the leading/from/%4/%5to keep it from rewriting to the root. So, for example, one of your rules should look like this: