Search code examples
phpapache.htaccessmod-rewritemod-alias

issue with URL redirection in Apache (mod_rewrite / mod_alias)


There are many issues related to Apache configuration with mod_rewrite and mod_alias on Stack Exchange but I couldn't find an answer to my issue, so here is another question! ;)

I migrated an old website to a new location.

Articles used to be accessible to an URL such as http://xxx/blog/index.php?post/YYYY/MM/DD/title, so there are many links of that form through the existing webpages.

Now, the URL should be http://xxx/post/YYYY/MM/DD/title, so just remove blog/index.php? from the final URL.

I wanted to use mod_alias and a Redirect clause, but I read here that the Redirect clause was interpreted after the RewriteRule clause, which is a problem in my case because I'm already using a RewriteRule condition.

Here is my current .htaccess file:

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1

I tried to modify it this way:

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/index.php? / [R=301,L]
RewriteRule ^(.*)$ index.php?$1

It almost works except:

  1. http://xxx/blog/index.php?post/YYYY/MM/DD/title is redirected/rewritten to http://xxx/blog/?post/YYYY/MM/DD/title (note the ?) so it doesn't work
  2. it looks like this new line messes up a lot of other URLs that do not start with /blog/index.php? such as the backend URL...

Any help will be more than welcome!

Edit (2014-07-16):

If I use the following rule:

RewriteRule ^/?blog/index\.php(.*)$ /$1 [R=301,L]

then going to http://xxx/blog/index.php?test takes me to http://xxx/?test which is almost correct (the interrogation mark is still a problem)!

But when I try to match the interrogation mark by adding \?:

RewriteRule ^/?blog/index\.php\?(.*)$ /$1 [R=301,L]

then it just stops working... Going there: http://xxx/blog/index.php?test just leaves me there!

Why is that?


Solution

  • Try adding this rule to the beginning of your set of rules:

    RewriteCond %{THE_REQUEST} \?post/([0-9]{4})/([0-9]{2})/([0-9]{2})/([^&\ ]*)
    RewriteRule ^index\.php$ /post/%1/%2/%3/%4? [L,R=301]
    

    so that it looks like:

    RewriteEngine on
    RewriteBase /
    
    RewriteCond %{THE_REQUEST} \?post/([0-9]{4})/([0-9]{2})/([0-9]{2})/([^&\ ]*)
    RewriteRule ^index\.php$ /post/%1/%2/%3/%4? [L,R=301]
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?$1