I've found a partial answer here.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.+)\.php - [F,L]
[works] www.example.com/file.php to redirect to 404
[works] www.example.com/file to serve under /file.php (without showing on address bar)
[works] www.example.com/folder/ to NOT redirect to 404
[does not work] www.example.com/folder/index.php to redirect to 404
I'm aware that www.example.com/folder/ is served as www.example.com/folder/index.php (without showing on address bar) because of DirectoryIndex
I've tried playing around and disabling DirectoryIndex but I just couldn't figure it out.
What I have so far:
# if file has a .php extension redirect to 404 page #
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php[\s?] [NC]
RewriteCond %{THE_REQUEST} !^[A-Z]{3,}\s/+index\.php(/[^\s\?]+)? [NC]
RewriteCond %{REQUEST_URI} !(.*)/index\.php$
RewriteRule ^(.*)$ 404.php [L]
# this makes files work without .php #
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L,QSA]
Try this,
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /yourfolder/index.php?/$1 [L]
</IfModule>
Try this code:
# if file has a .php extension redirect to 404 page #
RewriteCond %{THE_REQUEST} \s.+?\.php[\s?] [NC]
RewriteCond %{REQUEST_URI} !/index\.php [NC]
RewriteRule ^ 404.php [L]
# this makes files work without .php #
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L,QSA]
Related
I've added a bounty of 50 to this question. I'm trying to make it so that:
all website pages show www.example.com/page/ - instead of /page. My current code below is only successful for www.example.com/page
How can the .htaccess code be corrected to achieve this?
Also, changing the canonical URL meta tags from www.mysite.com/page to www.example.com/page/ - will www.example.com/page/ show up in search engines instead of /page ?
The current .htaccess code is:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} ^ example.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Note that the first rewriting conditions just forward to www. and https, so the only part that might need editing might just be:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
So all I want to do it simply add a '/'. A wordpress blog (presumably PHP files rather than HTML) that achieves my wants on the same website (it's at www.example.com/blog/) has htaccess code being:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress
I'm not sure how this works but I'd love to learn more about .htaccess and redirects, but nothing much seems to be on the web for beginners. I've also read this post. It also must be https (not sure why but blog posts also can have a http link, whereas other pages redirect to https).
The website also has a blog (php files) on it with its own htaccess file, installed under example.com/blog/ - the htaccess code is the default wordpress one:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress
Have your .htaccess as this in site root:
RewriteEngine On
# force www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
# force https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
# remove .php or .html extensions
RewriteCond %{THE_REQUEST} \s/+(.+?)\.(?:html|php)[\s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]
# add trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301,NE]
# add .html extension
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+?)/?$ $1.html [L]
# add .html extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
For issues with relative paths for css/js/images add this just below <head> section of your page's HTML:
<base href="/" />
This works for me, the top one is excluding .php from the URL and the bottom one excludes .html from the URL.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html [NC,L]
I've got the following htaccess file:
RewriteEngine On
RewriteBase /
# Redirect to remove .php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
# Redirect to "page" for dynamic pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ page?url=/$1 [L]
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1%{REQUEST_URI} [R=301,QSA,NC,L]
This allows my custom CMS to use dynamic URLs (http://example.com/some-page, for example) and redirect it to http://example.com/page?url=some-page so that the CMS can render the content. It all works great - until someone adds a URL like http://example.com/something/else. When I spit out the url parameter with: print $_GET['url']; I get /something/else.php/else.
So it seems like the remove .php directive is getting lost and the second parameter is getting duplicated? Thanks for any help.
Have it this way:
Options -MultiViews
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,NE,L]
RewriteCond %{ENV:REDIRECT_STATUS} =200
RewriteRule ^ - [L]
# Redirect to remove .php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^/]+)/?$ $1.php [L]
# Redirect to "page" for dynamic pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule !^page\.php$ page.php?url=%{REQUEST_URI} [L,NC,QSA]
Here are changes:
Keep redirect rule before rewrite rules otherwise when www is removed from a URL then your internal URL will be exposed.
Use page.php in target instead of page to avoid another rewrite rule execution.
Use [L] flag in .php adding rule.
Addition of Options -MultiViews
This is what my .htaccess file looks like:
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
#removes trailing slash if not a directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=301,L]
#adds ".php" to a URL that isn't a directory or a file
RewriteCond %{REQUEST_URI} !(\.[^./]+)$
RewriteCond %{REQUEST_fileNAME} !-d
RewriteCond %{REQUEST_fileNAME} !-f
RewriteRule (.*) $1.php [L]
Although it lets me access the url without the .php in the end for e.g. example.com/sign-up
It does not redirect me from example.com/sign-up.php to example.com/sign-up
Is there any code which I can add to this file to make that happen?
Any insight would be very helpful
Try This :
RewriteEngine On
# browser requests PHP
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^\ ]+)\.php
RewriteRule ^/?(.*)\.php$ /$1 [L,R=301]
# check to see if the request is for a PHP file:
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^/?(.*)$ /$1.php [L]
I cannot answer this in comments so posting this as an answer:
RewriteEngine On
# remove PHP from root level requests
RewriteCond %{THE_REQUEST} \.php[\s?] [NC]
RewriteRule ^([^/]+)\.php$ /$1 [R=302,NE,L,NC]
# To internally redirect /foo to /foo.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^/]+)/?$ $1.php [L]
Here is my .htaccess on a Linux system:
ErrorDocument 401 ./error/
ErrorDocument 403 ./error/
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://www.website.co.uk/$1/ [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [QSA]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.website.co.uk/$1 [R=301,L]
Everything works as it should; www is added to non-www requests and a trailing slash is added. However when visiting www.website.com (which is added as a parked domain on cPanel) the user is NOT redirected to www.website.co.uk
If the visit website.com (note no www) then they ARE redirected.
What do I need to add/change in .htaccess?
Have your rules like this:
ErrorDocument 401 ./error/
ErrorDocument 403 ./error/
RewriteEngine on
RewriteBase /
# if not www.website.co.uk then redirect to it
RewriteCond %{HTTP_HOST} !^www\.website\.co\.uk$ [NC]
RewriteRule ^(.*)$ http://www.website.co.uk/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ http://www.website.co.uk/$1/ [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [L,QSA]
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]
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>
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]
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>