I have a multidomain setup that looks like this on my server … this is a model of the structure:
.htaccess
***my-website
.htaccess
index.php
projects.php
jobs.php
some-project.php
another-project.php
some-job.php
another-job.php***
other-domain
other-domain
other-domain
I have two goals:
1.) The root .htaccess file should just make sure, that my main-domain which is /my-website is run/executed automatically when entering www.my-website.com. Due to the fact that I have a multidomain ftp-server I need do specify that. That is working already.
2.) In my sub-directory /my-website I need some different rules, especially regarding better url design and the omittance of .php extension.
So in /my-website I want to neglect all .php suffixes.
And I want to "fake" directories like /jobs /projects which are actually not directories but php-files themselves.
This is what I have so far thanks to #anubhava in this thread.
DocumentRoot/.htaccess:
RewriteEngine On
RewriteBase /
RewriteRule ^projects/(.+?\.php)$ /$1 [L,NC]
RewriteRule ^jobs/(.+?\.php)$ /$1 [L,NC]
RewriteRule ^(downloads/.+)/?$ assets/$1 [L,NC]
# add .php extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f [NC]
RewriteRule ^(.+?)/?$ $1.php [L]
RewriteCond %{REQUEST_URI} !^/my-website/
RewriteCond %{DOCUMENT_ROOT}/my-website%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/my-website%{REQUEST_URI} -d
RewriteRule ^(.*)$ /my-website/$1 [L]
/my-website/.htaccess:
RewriteEngine On
RewriteBase /my-website/
# add .php extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/my-website/$1\.php -f [NC]
RewriteRule ^(.+?)/?$ $1.php [L]
However I have the problem now when using this, that in my-website the links without a trailing .php wont work. I want my links to work like /projects but run/exectute /projects.php in my-website. However this doesn't work at the moment, i get a 404.
I also want /projects/some-project to run/execute /some-project.php (where the projects directory doesn't actually exist) which doesn't work either, also 404.
So, to sum it up.
All my domains work now! So my multidomain-setup is save and handeld.
However inside /my-website I want all links to work without trailing .php and with this "faked" directories
So right now this works …
www.my-website.com // works
www.other-domain.com // works
www.my-website.com/projects // doesn't work without trailing .php
www.my-website.com/projects.php // works (runs projects.php)
www.my-website.com/projects/some-project // doesn't work (should run some-project.php)
www.my-website.com/projects/some-project.php // works (runs some-project.php)
Have root .htaccess like this:
RewriteEngine On
RewriteBase /
## COMMENT out these 2 rules
# RewriteRule ^projects/(.+?\.php)$ /$1 [L,NC]
# RewriteRule ^jobs/(.+?\.php)$ /$1 [L,NC]
RewriteRule ^(downloads/.+)/?$ assets/$1 [L,NC]
# add .php extension
RewriteCond %{DOCUMENT_ROOT}/my-website/$1\.php -f [NC]
RewriteRule ^(?:[^/]+/)?([^/]+)/?$ my-website/$1.php [L]
RewriteCond %{HTTP_HOST} ^(www\.)?my-website\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/my-website/ [NC]
RewriteRule ^(.*)$ my-website/$1 [L]
# add .php extension 2
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f [NC]
RewriteRule ^(?:[^/]+/)?([^/]+)/?$ $1.php [L]
/my-website/.htaccess:
RewriteEngine On
RewriteBase /my-website/
# add .php extension
RewriteCond %{DOCUMENT_ROOT}/my-website/$1\.php -f [NC]
RewriteRule ^(?:[^/]+/)?([^/]+)/?$ $1.php [L]
DocumentRoot/.htaccess:
RewriteBase /
RewriteRule ^projects/(.+?\.php)$ /$1 [L,NC]
RewriteRule ^jobs/(.+?\.php)$ /$1 [L,NC]
RewriteRule ^(downloads/.+)/?$ assets/$1 [L,NC]
# add .php extension for REQUEST_FILENAME existing in /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f [NC]
RewriteRule ^(.+?)/?$ $1.php [L]
# Check if REQUEST_URI is existing as file or directory in /my-website
RewriteCond %{REQUEST_URI} !^/my-website/
RewriteCond %{DOCUMENT_ROOT}/my-website%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/my-website%{REQUEST_URI} -d
RewriteRule ^(.*)$ /my-website/$1 [L]
# Check if REQUEST_URI is existing as file.php in /my-website
RewriteCond %{REQUEST_URI} !^/my-website/
RewriteCond %{DOCUMENT_ROOT}/my-website%{REQUEST_URI}.php -f
RewriteRule ^(.*)$ /my-website/$1 [L]
/my-website/.htaccess:
RewriteEngine On
RewriteBase /my-website/
# To internally forward /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
Related
Im running apache with xampp. I've done some changes to hide files' type at link. After a while I noticed that adding href with directory, adds same directory again to link like so:
/dir into /dir/dir and then dir/dir/dri ....
and for hrefs at current directory, it sends me to certain page - page that was in script for .htaccess. Guess it's been because my IDE autosaves file as I add it and it had overriden defaults before I've set the right properties.
Code that I put to .htaccess:
RewriteEngine On
# Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ http://example.com/folder/$1 [R=301,L]
# Redirect external .php requests to extensionless URL
RewriteCond %{THE_REQUEST} ^(.+)\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(.+)\.php$ http://example.com/folder/$1 [R=301,L]
# Resolve .php file for extensionless PHP URLs
RewriteRule ^([^/.]+)$ $1.php [L]
Can I somehow revert this changes / go back to default?
If I delete file, try to override with similar code it still doesn't fix the problem.
DirectorySlash Off
RewriteEngine on
RewriteCond %{THE_REQUEST} \s/+(.*?/)?(?:index)?(.*?)\.(php|html)[\s?/] [NC]
RewriteRule ^ /%1%2 [R=302,L,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*) /$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*) /$1.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\/$
RewriteRule ^(.*) %{REQUEST_URI}/ [L,R=302]
This works - Extension goes off and works with new files and directories. Previous one I can't repair...
My website runs a script called -> WSS wallpaper script
My Problem -> I have been trying to force remove or add trailing slash to the end of my URL to prevent duplicated content and also to clean up my URLs.
I have tried all sorts and tried everything I could think of and loads from the interwebs but no such luck yet! It might be a quick fix but I have looked at it so much I am probably blind to something dead obvious.
So I present you with all my .htaccess code:
DirectoryIndex index.php
RewriteEngine on
RewriteRule ^download/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) image.php?id=$1&width=$2&height=$3&cropratio=$4&download=1 [L]
RewriteRule ^file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) image.php?id=$1&width=$2&height=$3&cropratio=$4 [L]
RewriteRule ^preview/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) wallpaper_preview.php?id=$1&width=$2&height=$3&name=$4 [L]
RewriteRule ^thumbnail/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/]+) image.php?wallpaper_id=$1&width=$2&height=$3&cropratio=$4&align=$5&valign=$6&file=$7 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+)/p([0-9]+) index.php?task=category&id=$1&name=$2&page=$3 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+)/([0-9a-zA-Z?-]+)/p([0-9]+) index.php?task=category&id=$1&name=$2&sortby=$3&page=$4 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+)/([0-9a-zA-Z?-]+)-([0-9]+) index.php?task=category&id=$1&sortby=$3&page=$4 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+) index.php?task=category&id=$1&name=$2 [L]
RewriteRule ^tag/([^/\.]+)/([0-9a-zA-Z?-]+)/([0-9]+) index.php?task=tag&t=$1&sortby=$2&page=$3 [L]
RewriteRule ^tag/([^/\.]+) index.php?task=tag&t=$1 [L]
RewriteRule ^profile/([0-9]+)?/([^/\.]+) index.php?task=profile&id=$1&name=$2 [L]
RewriteRule ^profile/comments/([0-9]+)?/([^/\.]+) index.php?task=users_comments&id=$1&name=$2 [L]
RewriteRule ^page/([0-9]+) index.php?task=view_page&id=$1 [L]
RewriteRule ^register index.php?task=register [L]
RewriteRule ^lost-password index.php?task=lost_pass [L]
RewriteRule ^links index.php?task=links [L]
RewriteRule ^news/item/([0-9]+)/([^/\.]+) index.php?task=news&id=$1 [L]
RewriteRule ^news/page([0-9]+) index.php?task=news&page=$1 [L]
RewriteRule ^members/([^/\.]+)-([^/\.]+)/page([0-9]+)? index.php?task=member_list&sort=$1&order=$2&page=$3 [L]
RewriteRule ^members index.php?task=member_list [L]
RewriteRule ^messages index.php?task=messages [L]
RewriteRule ^submit index.php?task=submit [L]
RewriteRule ^search/([^/\.]+) index.php?task=search&q=$1 [L]
RewriteRule ^search index.php?task=search [L]
RewriteRule ^submit index.php?task=submit [L]
RewriteRule ^r-([0-9]+)?-([0-9]+)? go.php?id=$1&ref=$2 [L]
RewriteRule ^r-([0-9]+)? go.php?id=$1 [L]
RewriteRule ^([^/\.]+)/([0-9]+)/([^/\.]+) index.php?task=view&id=$2&name=$3 [L]
RewriteRule ^news/([^/\.]+) index.php?task=news&name=$1 [L]
RewriteRule ^profile/([^/\.]+) index.php?task=profile&name=$1 [L]
RewriteRule ^news index.php?task=news [L]
RewriteRule ^page/([^/\.]+) index.php?task=view_page&name=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+)/([0-9a-zA-Z'?-]+)/([0-9]+) index.php?task=category&name=$1&sortby=$2&page=$3 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+)/([^/\.]+) index.php?task=view&name=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+) index.php?task=category&name=$1 [L]
## www reslove ##
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
## www reslove ##
## index reslove ##
Options +FollowSymLinks
RewriteCond %{THE_REQUEST} ^.*/index\.php
RewriteRule ^(.*)index.php$ http://www.epicwallpaper.net/$1 [R=301,L]
## index reslove ##
Right below the RewriteEngine On line, add:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R] # <- for test, for prod use [L,R=301]
to enforce a no-trailing-slash policy.
To enforce a trailing-slash policy:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R] # <- for test, for prod use [L,R=301]
EDIT: commented the R=301 parts because, as explained in a comment:
Be careful with that R=301! Having it there makes many browsers cache the .htaccess-file indefinitely: It somehow becomes irreversible if you can't clear the browser-cache on all machines that opened it. When testing, better go with simple R or R=302
After you've completed your tests, you can use R=301.
To complement Jon Lin's answer, here is a no-trailing-slash technique that also works if the website is located in a directory (like example.org/blog/):
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [R=301,L]
For the sake of completeness, here is an alternative emphasizing that REQUEST_URI starts with a slash (at least in .htaccess files):
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /(.*)/$
RewriteRule ^ /%1 [R=301,L] <-- added slash here too, don't forget it
Just don't use %{REQUEST_URI} (.*)/$. Because in the root directory REQUEST_URI equals /, the leading slash, and it would be misinterpreted as a trailing slash.
If you are interested in more reading:
PR 3145 for Laravel
A discussion on commit 343c31e
(update: this technique is now implemented in Laravel 5.5)
This is what I've used for my latest app.
# redirect the main page to landing
##RedirectMatch 302 ^/$ /landing
# remove php ext from url
# https://stackoverflow.com/questions/4026021/remove-php-extension-with-htaccess
RewriteEngine on
# File exists but has a trailing slash
# https://stackoverflow.com/questions/21417263/htaccess-add-remove-trailing-slash-from-url
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.*)/+$ /$1 [R=302,L,QSA]
# ok. It will still find the file but relative assets won't load
# e.g. page: /landing/ -> assets/js/main.js/main
# that's we have the rules above.
RewriteCond %{REQUEST_FILENAME} !\.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^/?(.*?)/?$ $1.php
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
## hide .html extension
# To externally redirect /dir/foo.html to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+).html
RewriteRule ^ %1 [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)/\s
RewriteRule ^ %1 [R=301,L]
## To internally redirect /dir/foo to /dir/foo.html
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^\.]+)$ $1.html [L]
<Files ~"^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</Files>
This removes html code or php if you supplement it. Allows you to add trailing slash and it come up as well as the url without the trailing slash all bypassing the 404 code. Plus a little added security.
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.
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]
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]
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]
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.
Below is my .htaccess file. I am trying to exclude the rewrite rules being applied to the /admin/ folder, however after spending an hour researching and trying various codes I have reached a wall.
Options -MultiViews
RewriteEngine On
RewriteBase /
# Exclude admin directory
RewriteRule ^(admin|admin)($|/) - [L]
RewriteRule ^privacy$ pages/privacy.php [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)/(.+)$ products.php?q=$3&rewrite=1&%{QUERY_STRING} [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)/$ search.php?q=bw:&categoryFilter=$1&genreFilter=$2%{QUERY_STRING} [L,B]
RewriteRule ^(.*)/$ pages/format.php?format=$1 [NC,L}
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]
The above code brings an internal 500 error and if I remove it will redirect me to the rewrite rule for the format. I was reading that The exclusion rewrite rule needs to be placed before the rule I want to overwrite. I don't understand why it's not working and what I have missed.
Thanks.
Try and write your rule this way.
# Exclude admin directory
RewriteRule ^admin/?$ - [L]
You have a syntax error in your .htaccess.
Have your .htaccess like this:
Options -MultiViews
RewriteEngine On
RewriteBase /
# Exclude admin directory
RewriteRule ^admin($|/) - [L,NC]
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^privacy$ pages/privacy.php [NC,L]
RewriteRule ^(.+)/(.+)/(.+)$ products.php?q=$3&rewrite=1 [L,QSA]
RewriteRule ^(.*)/(.*)/$ search.php?q=bw:&categoryFilter=$1&genreFilter=$2 [L,B,QSA]
RewriteRule ^(.+)/$ pages/format.php?format=$1 [NC,L]
i know there are many questions like "How do i remove the .php extension, so that /test/ will be /test.php"
but if the user directly goes to test.php it doesnt replace the extension.
So I want to replace the .php it should be /.
here is the part of the .htacces I'm using:
RewriteEngine on
RewriteRule stuff\.php /other_stuff/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^/]+)/$ $1.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
You need to do the check against the actual request instead of the URI (which gets rewritten by other rules). The %{THE_REQUEST} variable doesn't change in the course of the rewrite engine. Try adding these rules right below the RewriteEngine directive:
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /([^/]+)\.php(\?|\ |$)
RewriteRule ^ /%2/ [L,R=301]