5

How can I have this in my htaccess:

/page.php => redirects to /page
/page => shows the page.php
/index => redirects to root

And how to remove trailing slashes from all URLs, specially the root one?

Although, I'm not familiar enough with Apache configs, but I could find these codes:

# To remove .php extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]

# To remove trailing slashes
RewriteRule ^(.*)/$ /$1 [L,R=301]

# To redirect /index to root (not sure if it works correctly)
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index.php$ /$1 [R=301,L]

Could you please help me with the scenario and have it in one small code?

Thanks


According to answers, I could solve the problem using the codes below in my .htaccess file:

# To remove .php extension
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ (.*)\.php [NC]
RewriteRule ^ %1 [R=301,L]

# To remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301,L]

# To check whether the file exists then set it back internally
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^.*$ $0.php [L]

# To redirect /index to root
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index.php$ /$1 [R=301,L]

Now, I got a new problem and that is when I browse the files with a trailing slash, it redirects me to somewhere else and occurs a 404 (page not found) response, like this:

http://domain.tld/page/ => http://domain.tld/page/home/user/public_html/domain.tld/page

Also, if I move the second part to the end or even remove it completely, the server sends me a 500 (internal server error) response.


Finally with a little research, I could find the solution for previous problem using this advice:

https://stackoverflow.com/a/27264788/5420319

So, I've changed one of the codes from this:

# To remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301,L]

To this:

# To remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /(.*)/$
RewriteRule ^ /%1 [R=301,L]

And I also moved this part to the top regardless of being effective.

Community
  • 1
  • 1
4L3X
  • 115
  • 1
  • 11

4 Answers4

4

According the the answers and my own research, this would be the final answer:

# To remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /(.*)/$
RewriteRule ^ /%1 [R=301,L]

# To remove .php extension
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ (.*)\.php [NC]
RewriteRule ^ %1 [R=301,L]

# To check whether the file exists then set it back internally
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^.*$ $0.php [L]

# To redirect /index to root
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index.php$ /$1 [R=301,L]
4L3X
  • 115
  • 1
  • 11
1

Redirecting page.php to /page:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ /page\.php [NC]
RewriteRule ^ /page [R=301,L]

Now, setting back internally to page.php:

RewriteRule ^page$ /page.php [NC,L]

Remove trailing slashes:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301,L]

Now, checking whether a file for /some/page/foo such that /some/page/foo.php exists:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^.*$ $0.php [L]
hjpotter92
  • 78,589
  • 36
  • 144
  • 183
  • there are some problems with your codes. for example, a tariling slash after the "page" occurs an internal error, while it suppose to redirect to the page without a trailing slash. The other problem us the last code does not work at all. when I browse the page.php it remains with extension and does not redirect to the no-extension form. Note that I didn't place the first and second code because of they were specific to the name of page, since I need something to work with all files not only the page.php – 4L3X Oct 08 '15 at 18:06
  • I've also tried your first code and it didn't work for that specific page. It redirects from /page.php to /page but after that I get a 404 response from the server for that. – 4L3X Oct 08 '15 at 18:15
  • @4L3X All the rules go in that specific order, in the same `.htaccess` file. – hjpotter92 Oct 08 '15 at 18:16
  • Also as I mentioned before in my comments, could you please provide a code that is not relying to the file name and works with everything not only the page.php? – 4L3X Oct 08 '15 at 18:26
  • @4L3X In the first rule (with %{THE_REQUEST}), change the pattern to: ^[A-Z]{3,}\ (.*)\.php [NC] and after that, RewriteRule ^ %1 [R=301,L] – hjpotter92 Oct 08 '15 at 19:00
  • @4L3X I'll go to sleep for now (2 AM here). Put the current code of your htaccess file in the question above and I (or anyone else) would be able to help you better. – hjpotter92 Oct 08 '15 at 20:20
  • OK, I've included the current problem in my question post. Thanks & have a good night – 4L3X Oct 08 '15 at 20:33
0

A cleaned up and simplified version of the accepted answer is:

# To remove trailing slash
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301,L]

# To remove .php extension
RewriteRule ^(.*)\.php$ $1 [R=301,L]

# To check whether the file exists then set it back internally
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}.php -f
RewriteRule ^.*$ $0.php [L]
gahooa
  • 131,293
  • 12
  • 98
  • 101
-2
Options +FollowSymLinks
RewriteEngine on
AddHandler php5.3-fastcgi php
SetEnv no-gzip dont-vary

RewriteRule ^([a-z]+)$                                                  index.php?page=$1                                   [QSA,L]
RewriteRule ^([a-z]+)/([a-z0-9]+)$                                      index.php?page=$1&subpage=$2                        [QSA,L]
RewriteRule ^([a-z]+)/([a-z0-9]+)/([a-z0-9]+)$                          index.php?page=$1&subpage=$2&module=$3              [QSA,L]
RewriteRule ^([a-z]+)/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)$              index.php?page=$1&subpage=$2&module=$3&submodule=$4 [QSA,L]

You can play with that.

Sates
  • 408
  • 1
  • 5
  • 21
  • This literally does no rewriting, would cause a 500, and doesn't answer the question. – Walf Nov 13 '16 at 11:07
  • This actually, literally, unexpectedly, unsurprisingly has been working ever since, Mr. Wise Ass. Otherwise I wouldn't be able to use it but I am able to use it and I do. And it works perfectly, causes no 500 and does rewrite the URL beautifully (btw. I posted the answer LAT YEAR on October, dude. So chill, cause you've just been caught up in mud twice now). Check-mate. But it does not answer the question precisely. That's the only thing I can agree with. – Sates Dec 28 '16 at 17:43
  • 1
    Working for you does not make it a solution to OP's question, nor a good general solution. It doesn't do redirects, as OP asked, can run into the bug that `DPI` fixes, could be replaced with one rule (if you were better at regexen), and has server-specific config littering it. It's a very low quality answer. Age of posts is irrelevant and "Check-mate"? WTF dude. – Walf Jan 04 '17 at 01:10