8

I work with a framework called SilverStripe ... we are currently in the process of migrating an old site onto this framework. The problem is that the old site URLs ended with .php or .html whilst in the new site they don't.

I need to amend the second rewrite rule in such a way that I pump the request to main.php without any .html or .php extensions.

In my current .htaccess I have the following rules:

# Turn off index.php handling requests to the homepage fixes issue in apache >=2.4
<IfModule mod_dir.c>
    DirectoryIndex disabled
</IfModule>

SetEnv HTTP_MOD_REWRITE On
RewriteEngine On

# Enable HTTP Basic authentication workaround for PHP running in CGI mode
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

# Deny access to potentially sensitive files and folders
RewriteRule ^vendor(/|$) - [F,L,NC]
RewriteRule silverstripe-cache(/|$) - [F,L,NC]
RewriteRule composer\.(json|lock) - [F,L,NC]

# Process through SilverStripe if no file with the requested name exists.
# Pass through the original path as a query parameter, and retain the existing parameters.
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* framework/main.php?url=%1 [QSA]

# If framework isn't in a subdirectory, rewrite to installer
RewriteCond %{REQUEST_URI} ^(.*)/framework/main.php$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . %1/install.php? [R,L]

Possible solution (still testing):

 RewriteCond %{REQUEST_URI} ^(.*)\.html [OR]
 RewriteCond %{REQUEST_URI} ^(.*)\.php [OR]
 RewriteCond %{REQUEST_URI} ^(.*)$
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteRule .* framework/main.php?url=%1 [QSA]
Gabriel Spiteri
  • 4,596
  • 10
  • 39
  • 57

5 Answers5

4

Add the following rules to your .htaccess file below the # Deny access to potentially sensitive files and folders block of rules:

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

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

The first two lines check that the url is not a directory and is not file.

The third line checks that the url contains either .html or .php.

The forth line removes .html / .php from the url

3dgoo
  • 15,356
  • 5
  • 44
  • 57
4

You can just tweak your existing rule a bit:

# Turn off index.php handling requests to the homepage fixes issue in apache >=2.4
<IfModule mod_dir.c>
    DirectoryIndex disabled
</IfModule>

SetEnv HTTP_MOD_REWRITE On
RewriteEngine On

# Enable HTTP Basic authentication workaround for PHP running in CGI mode
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

# Deny access to potentially sensitive files and folders
RewriteRule ^vendor(/|$) - [F,L,NC]
RewriteRule silverstripe-cache(/|$) - [F,L,NC]
RewriteRule composer\.(json|lock) - [F,L,NC]

# Process through SilverStripe if no file with the requested name exists.
# Pass through the original path as a query parameter, and retain the existing parameters.
# Strip out .html or .php from request URI
RewriteCond %{REQUEST_URI} ^(.+?)(?:\.(?:html|php))?$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ framework/main.php?url=%1 [L,QSA]

# If framework isn't in a subdirectory, rewrite to installer
RewriteCond %{REQUEST_URI} ^(.*)/framework/main\.php$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . %1/install.php? [R,L]
anubhava
  • 664,788
  • 59
  • 469
  • 547
3

Here is a short solution to the problem

Try the following rule :

RewriteRule ^([^.]+)\.(html|php)$ /framework/main.php?url=$1 [NC,L,QSA]

This will rewrite

/file.php OR /file.html

to

   /framework/main.php?url=$1

pattern explained :

^([^.]+).(html|php)$ matches any request starting with any characters excluding dot followed by a littrel dot char followed by literal php or html in the end of the uri.

Note : this should be the first rule in your htaccess before any other rules.

Amit Verma
  • 38,175
  • 19
  • 80
  • 104
3

Try this code:-

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

RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_FILENAME}\.html -f 
RewriteRule ^(.*)$ $1.html

Hope this code will work for you :)

Ravi
  • 5,913
  • 1
  • 20
  • 37
0

How about the basic...

Redirect 301 /about-us.html http://www.domain.com/about-us

EDIT Now you've mentioned that you have hundreds of these... the above answer is still valid as you can add hundreds of these to the htaccess (I've seen it many times)... however it is very possible also like this...

RedirectMatch 301 (.*)\.html$ http://www.domain.com$1/

The downside of not doing this line by line is now that you may have a specific html file that you do want to allow access to still and that will need adding as an exception to this rule.

Barry
  • 3,109
  • 7
  • 20
  • 40