Question

I'm using the following in my .htaccess file but it doesn't seem to be working correctly.

Redirect 301 top_users.php http://example.com/top-users
RewriteRule ^top-users/?$ top_users.php

Redirect 301 register.php http://example.com/register
RewriteRule ^register/?$ register.php

Redirect 301 register.php?log=1 http://example.com/login
RewriteRule ^login/?$ register.php?log=1

The top users page seems to be working fine, and it works fine if i go straight to /login or /register, but the redirect isn't working. I've tried adding a forward slash before the redirect page name but it gives me the wrong path and says it cannot be found.

Any ideas?

EDIT:

UPDATE:

The final code i used was as below, thanks to Jon Lin for the help.

RewriteEngine On
RewriteBase /
Options +FollowSymLinks

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /top-users(/|$|\ )
RewriteRule ^top-users(/|$|\ ) top_users.php [L]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /top_users\.php
RewriteRule ^top_users\.php$ http://example.com/top-users/ [R=301]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /register(/|$|\ )
RewriteRule ^register(/|$|\ ) register.php [L]

# check if request for register.php does not include log=1 in query string
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /register\.php
RewriteCond %{QUERY_STRING} !log=1
RewriteRule ^register\.php$ http://example.com/register/ [R=301]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /login(/|$|\ )
RewriteRule ^login(/|$|\ ) register.php?log=1 [L,QSA]

# check if request for register.php includes log=1 in query string
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /register\.php
RewriteRule ^register\.php$ http://example.com/login/? [R=301]
Était-ce utile?

La solution

You are causing a redirect loop. You should be redirecting when the original request is for the php file, and rewriting when the original request is for the nicer looking URI:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /top-users(/|$|\ )
RewriteRule ^top-users top-users.php [L]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /top-users\.php
RewriteRule ^top-users\.php$ http://example.com/top-users/ [R=301]

etc...

For the other 2 you need to match against query string:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /register(/|$|\ )
RewriteRule ^register register.php [L]

# check if request for register.php does not include log=1 in query string
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /register\.php
RewriteCond %{QUERY_STRING} !log=1
RewriteRule ^register\.php$ http://example.com/register/ [R=301]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /login(/|$|\ )
RewriteRule ^login register.php?log=1 [L,QSA]

# check if request for register.php includes log=1 in query string
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /register\.php
RewriteCond %{QUERY_STRING} (^|&)log=1(&|$)
RewriteRule ^register\.php$ http://example.com/login/ [R=301]

You cannot match against the query string in a Redirect or RewriteRule. You have to do it using a RewriteCond %{QUERY_STRING}

Autres conseils

Why not using the mod_rewrite flags? You could edit every two lines into one in the following manner

<IfModule mod_rewrite.c>

RewriteEngine On
RewriteBase /
Options +FollowSymLinks

RewriteRule ^top-users(/?)$ top_users.php [L,QSA,R=301]

</IfModule>

QSAstands for Query String Append, for any GET parameters and with R=301 you replace the preceding line of each of your rules.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top