Search code examples
.htaccessmod-rewrite

.htaccess rewrite to same alias without infinite redirects


I have...

| .htaccess : (v1)

RewriteEngine on

RewriteRule ^in?$ login.php

So, /in --is-really--> /login.php

This much works great. We all can learn how to do this from: .htaccess redirect with alias url

But, I want it to also work in reverse...

If someone should enter /login.php into the address bar, I want it to change to /in.

So also, /login.php --rewrites-to--> /in

From this Answer to a different Question, I want to be ready for anything, using REQUEST_URI. So, my .htaccess file starts with this...

| .htaccess : (v2)

RewriteEngine on

# Remove index.php, if a user adds it to the address
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+/)?index\.php
RewriteRule (^|/)index\.php(/|$) /%1 [R=301,L]

# "in" --> login.php
RewriteRule ^in?$ login.php

That also works great.

But now, I want to add this rule (my Question here) for /in <--> /login.php both ways, just how / <--> /index.php already works with .htaccess (v2). So, I adopted the settings and added a second rule...

| .htaccess : (v3) —not working!

RewriteEngine on

# Remove index.php, if a user adds it to the address
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+/)?index\.php
RewriteRule (^|/)index\.php(/|$) /%1 [R=301,L]

# "in" --> login.php, and also redirect back to it
RewriteCond %{REQUEST_URI} ^/(.+/)?login\.php
RewriteRule (^|/)login\.php(/|$) /%1in [R=302,L]
RewriteRule ^in?$ login.php

...but then /in and /login.php both cause an infinite redirect loop.

What's the right way to do this, still using REQUEST_URI, and still having both rewrite rules (for index.php and for login.php)?


These Questions did not help:


Solution

  • Reason of redirect loop is a missing RewriteCond %{ENV:REDIRECT_STATUS} ^$ before first redirect rule that removes index.php. Remember that RewriteCond is applicable to immediate next RewriteRule only.

    Suggested .htaccess:

    RewriteEngine on
    
    # Remove index.php, if a user adds it to the address
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteCond %{REQUEST_URI} ^/(.+/)?index\.php$ [NC]
    RewriteRule ^ /%1 [R=301,L]
    
    # "in" --> login.php, and also redirect back to it
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteCond %{REQUEST_URI} ^/(.+/)?login\.php$ [NC]
    RewriteRule ^ /%1in [R=302,L]
    
    RewriteRule ^in?$ login.php [L,NC]
    

    It won't cause redirect loop because after first rewrite to /login.php, variable REDIRECT_STATUS will become 200 and then the RewriteCond %{ENV:REDIRECT_STATUS} ^$ will stop redirect looping.