1

Using .htaccess, I'd like to redirect files that do not exist to a controller page, and rewrite the extension of .php files that do exist to an .html extension. If a file exists and is an .html page, I'd like it to remain the same. Every time I try to inject the rewrite rule from .php to .html, I seem to mess up the redirect to the controller page. So I'm not sure where to go from here:

Options -Indexes
Options +FollowSymLinks
DirectoryIndex index.php
ErrorDocument 404 /404.php

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(.*)$ mycontroller.php [L,QSA]
</IfModule>

Any help I'd be most grateful for.

Edit

I seem to have found most of the answer here (but I have to leave out the ReweriteBse or it doesn't work). The biggest issue is that now, my existing .html files don't work, it only serves my .php files with .html extensions and directs all else to the controller. Existing .html files go to my 404 page. I'd like to know how I can keep my existing .html files intact. My new code as follows:

  RewriteEngine on

  RewriteCond %{THE_REQUEST} (.*)\.php  
  RewriteRule ^(.*)\.php $1.html [R=301,L]  

  RewriteCond %{THE_REQUEST} (.*)\.html  
  RewriteRule ^(.*)\.html $1.php [L]  

  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(.*)$ mycontroller.php [L,QSA]
Community
  • 1
  • 1
seaofinformation
  • 809
  • 2
  • 12
  • 19

3 Answers3

1

Try:

<IfModule mod_rewrite.c>
  RewriteEngine on

  # If a request for a php file is made, check that it's actually a php file then redirect the browser
  RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*?)\.php($|\ )
  RewriteCond %{REQUEST_FILENAME} -f
  RewriteRule ^(.*?)\.php$ /$1.html [L,R=301]

  # If a request for an html file is made, check that it's a php file, and if so, serve the php file:
  RewriteCond %{REQUEST_URI} ^/(.*?)\.html$
  RewriteCond %{DOCUMENT_ROOT}/%1.php -f
  RewriteRule ^ /%1.php [L]

  # Everything else goes to the controller
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(.*)$ mycontroller.php [L,QSA]
</IfModule>
Jon Lin
  • 142,182
  • 29
  • 220
  • 220
  • Thank for your answer! I copied and pasted this exactly and I'm still getting "No input file specified." for everything but .php files, and I have to type the .php extension. – seaofinformation Sep 14 '12 at 00:07
  • @seaofinformation This is a Apache <-> PHP engine issue, not sure exactly why this happens, but try adding a `RewriteBase /` right after the `RewriteEngine On` directive. – Jon Lin Sep 14 '12 at 00:10
  • I also realized that I uploaded the .htaccess incorrectly (my FTP client messes it up). Now that it's uploaded properly, it's interesting the result -- for pages that exist or when it's being directed to the controller, I get a "The page you requested is not available, a general error has occurred". If I add an .html extension to .php files that exist, it just goes to my 404 page. This all still happens even if I add the RewriteBase / line. – seaofinformation Sep 14 '12 at 00:31
  • After digging around I figured out most of the answer, I edited my question. Maybe you can help -- my .php extensions are being replaced with .html extensions as desired, and the redirect to the controller is working, but my existing .html files go to my 404 page. I think it's because the code is looking for .php files to rewrite extensions to .html, but I don't know how to get it to leave alone existing files that already have .html extensions. – seaofinformation Sep 14 '12 at 23:42
  • @seaofinformation it should rewrite anything if there isn't an existing PHP file, your HTML files shouldn't be affected – Jon Lin Sep 14 '12 at 23:45
  • Did you see the edit of my question? I'm not using the code you gave since I couldn't get it to work, I used another, and unfortunately it doesn't recognize my existing .html files. – seaofinformation Sep 15 '12 at 00:04
  • 1
    @seaofinformation you need the `-f` checks in my answer. That ensures what you are rewriting to is something that's actually there instead of blindly rewriting everything – Jon Lin Sep 15 '12 at 00:26
0

Try this (I have added a rewrite condition to avoid an infinite loop b yadding the parameter r=0 and testing if it exists) :

  RewriteEngine on

  RewriteCond %{QUERY_STRING} ^(.*&)?r=0(&.*)?$
  RewriteRule ^(.*)\.php$ $1.html [L,R=301,QSA]

  RewriteCond %{REQUEST_FILENAME} ^(.*)\.html$
  RewriteCond %1.php -f
  RewriteRule ^(.*)\.html$ $1.php?r=0 [L,QSA]

  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(.*)$ mycontroller.php [L,QSA]
Oussama Jilal
  • 7,669
  • 2
  • 30
  • 53
  • Thanks for the fast response! I put it in and now I'm getting "No input file specified." for everything but the .php files which exist (and I have to type them in as .php). – seaofinformation Sep 13 '12 at 11:11
  • ok maybe my fifth line is causing the problem, let me think about it – Oussama Jilal Sep 13 '12 at 11:23
  • I should qualify that -- I was uploading the .htaccess incorrectly. Now that I've uploaded it correctly, there just seems to be no change. If I type in .html, it doesn't serve the corresponding .php page if it exists, just goes to 404 error. – seaofinformation Sep 14 '12 at 00:19
0

I'm sure there are better ways to do this, but the following works for my needs. The other answers provided didn't seem to work despite my attempts.

Options -Indexes
Options +FollowSymLinks
DirectoryIndex index.php
ErrorDocument 404 /404.php

<IfModule mod_rewrite.c>
  RewriteEngine on

  # Check if .html file already exists -- if so, do nothing
  RewriteCond %{REQUEST_FILENAME} -f
  RewriteCond %{THE_REQUEST} (.*)\.html  
  RewriteRule ^.*$ - [NC,L] 

  # Check if .php file already exists -- if so, rewrite extension to .html
  RewriteCond %{REQUEST_FILENAME} -f
  RewriteCond %{THE_REQUEST} (.*)\.php  
  RewriteRule ^(.*)\.php $1.html [R=301,L]  

  RewriteCond %{THE_REQUEST} (.*)\.html  
  RewriteRule ^(.*)\.html $1.php [L]  

  # All else goes to the controller page
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(.*)$ mycontroller.php [L,QSA]
</IfModule>
seaofinformation
  • 809
  • 2
  • 12
  • 19