Hide index.php AND .php from URLs while using QUERY_STRING - .htaccess

I'd like to be able to hide both index.php and .php from my URLs while using QUERY_STRING.
Right now, I'm successfully hiding index.php (except when accessing certain directories) with the following in my .htaccess:
RewriteEngine On
RewriteCond $1 !^(codex|_core|admin|index\.php) [NC]
RewriteRule ^(.*)$ /index.php?/$1 [L]
I'm doing this because I have certain functions, such as login/logout/registration, acting as pages: example.com/login
However, I also have some static pages that wouldn't benefit from being inside one file with a bunch of PHP functions... such as example.com/terms-and-conditions.php
In the spirit of being uniform, how do I turn that URL into example.com/terms-and-conditions without breaking example.com/login? Is this even possible? I've tried adding the .php removal rewrite about the index.php removal rewrite (obviously removing the .php from index.php) to no avail.
I did try using the solution located here but it broke example.com/login — I assume because the way I'm using functions/queries. Is there just something small I need to change there?

Figured it out! Just needed to combine the two, which seems obvious in retrospect. :)
RewriteEngine On
# remove .php; use THE_REQUEST to prevent infinite loops
RewriteCond %{HTTP_HOST} ^www\.domain\.com
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP
RewriteRule (.*)\.php$ $1 [R=301]
RewriteCond $1 !^(codex|_core|admin|index\.php) [NC]
RewriteRule ^(.*)$ /index.php?/$1 [L]
# remove slash if not directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/ $1 [R=301]
# add .php to access file, but don't redirect
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]

Related

.htaccess Display shorter url in address bar that points to a real server folder path

I'm trying to shorten my urls in the address bar and for Google indexation purposes. For example, a real server directory path
http://www.somewebsite.com/path1/path2/path3/
would display
http://www.somewebsite.com/path3/
I've found many similar topics but no answer that seems to work for this particular case.
I have for example:
RewriteRule ^path3(.*)$ path1/path2/path3$1 (tried with with [L], [QSA,l], [R=301,...]...)
But this simply does a redirect and does not keep the short address in the browser.
My .htaccess file looks as follow:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# Use UTF-8 encoding for anything served as `text/html` or `text/plain`.
AddCharset UTF-8 .html
# Force www.
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# remove .php; use THE_REQUEST to prevent infinite loops
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP
RewriteRule (.*)\.php$ $1 [R=301]
# remove index
RewriteRule (.*)/index$ $1/ [R=301]
# remove slash if not directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/ $1 [R=301]
# add .php to access file, but don't redirect
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
#Trying to have a shorter url in address bar
RewriteRule ^path3(.*)$ path1/path2/path3$1
Converting my comments to answer so that solution can be easily found for the problem stated.
There are couple of issues with the rules shown in question:
Since target paths are pointing to an existing directory and you don't have trailing / in target it is causing an external redirect by mod_dir module of Apache that appends a / at the end of directory path and performs a 301 redirect.
Incorrect positioning of rule.
Not critical but missing L and NE (no escape) flag from redirect rules which may cause problems for some cases.
With those suggestion final working .htaccess can be like this:
# Use UTF-8 encoding for anything served as `text/html` or `text/plain`.
AddCharset UTF-8 .html
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# Force www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
# remove .php and index; use THE_REQUEST to prevent infinite loops
RewriteCond %{THE_REQUEST} \s/+(.*?/)?(?:index|(\S+?))\.php[/\s?] [NC]
RewriteRule ^ /%1%2 [R=301,L,NE]
# remove slash if not directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/$ $1 [R=301,L,NE]
# rewrite path3/ to /path1/path2/path3/
RewriteRule ^path3/.*$ path1/path2/$0 [L,NC]
# add .php to access file, but don't redirect
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*?)/?$ $1.php [L]
The example you provided works for myself on my own test website, using the below .htaccess rewrite:
RewriteEngine On
RewriteRule ^test2.txt/?$ /test.txt
This lets me have an optional trailing slash, and show the content of test.txt on /test2.txt.
Assuming your rewrite engine is on, can you replicate this behaviour? What version of Apache are you using? Is the path handled by a CMS at all?

Clean URLs in a subfolder

I've read and followed guides and looked for answers to other people's questions, but I'm struggling with url rewriting and htaccess.
I have a subfolder on my site with an index page which handles query strings to bring up dynamic content. I'd like the variable to appear to be a subfolder name e.g.
http://mywebsite.com/subfolder/index.php?v=variable
to
http://mywebsite.com/subfolder/variable
The .htaccess file I've made is at http://mywebsite.com/subfolder/ i.e. the same folder as index.php
How can I get this to work? Any help gratefully appreciated.
You can use these rules inside your /subfolder/.htaccess
RewriteEngine On
RewriteBase /subfolder/
RewriteCond %{THE_REQUEST} \s/subfolder/index\.php\?v=([^&\s]+) [NC]
RewriteRule ^ %1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)$ index.php?v=$1 [L]
Update (passing two values)
RewriteEngine On
RewriteBase /subfolder/
RewriteCond %{THE_REQUEST} \s/subfolder/index\.php\?v=([^&\s]+)&v2=([^&\s]+)\s [NC]
RewriteRule ^ %1/%2? [R=301,L]
RewriteCond %{THE_REQUEST} \s/subfolder/index\.php\?v=([^&\s]+)\s [NC]
RewriteRule ^ %1? [R=301,L]
# Don't touch to existing files/folders
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# Rewrite /xxx to /index.php?v=xxx
RewriteRule ^([^/]+)$ index.php?v=$1 [L]
# Rewrite /xxx/yyy to /index.php?v=xxx&v2=yyy
RewriteRule ^([^/]+)/([^/]+)$ index.php?v=$1&v2=$2 [L]
Use this in your .htaccess:
RewriteEngine On
RewriteCond %{QUERY_STRING} v=(.+)$ [NC]
RewriteRule ^ subfolder/%1? [R=301,L,NE]
This grabs the variable using %{QUERY_STRING} and then appends it to the rewrite using %1. You'll see I've added a ? onto the end of the rewrite. That is to stop the original query from appearing on the end of the URL.
I've used R=301 which is a permanent redirect. You might want to changes this to R=302 while you're testing, as this is temporary.
You can view a test of this rule working here: https://htaccess.madewithlove.be?share=7b6832e9-2c05-5d1d-916c-e4dd0f5b1da6
Make sure you clear your cache before testing this.

Hiding .php extension through .htaccess works fine, but not for one page

I'm trying to hide the .php file extension, it's working fine, but one page doesn't. All the files are in the root. When I try to visit the gastenboek (guestbook) I get a 404 error page. Some files of the guestbook are in a folder, like messages, send and captcha. But the main file of that page (Gastenboek.php) is in the root. There is another page, the forum, this is also in a folder, but that page is working just fine. How is it possible that the Gastenboek doesn't show up, and the forum does? What am I doing wrong? This is the code:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^slotraceclub.nl$
RewriteRule (.*) http://www.slotraceclub.nl/$1 [R=301,L]
# remove .php; use THE_REQUEST to prevent infinite loops
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP
RewriteRule (.*)\.php$ $1 [R=301]
# remove index
RewriteRule (.*)/index$ $1/ [R=301]
# remove slash if not directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/ $1 [R=301]
# add .php to access file, but don't redirect
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
</IfModule>

How to allow some specifics URLs and rest of others would be redirect to maintenance page

I have an issue on my htaccess file..
http://www.example.com/customer/contract/download
http://www.example.come/customer/contract/upload
These above urls should work and rest of other urls should redirect to maintenance.html.
How can i defined these cases on my htaccess file ??
Here is my htaccess code..
RewriteEngine on
IndexIgnore *
RewriteCond $1 !^(index\.php|public|images|robots\.txt|favicon\.ico|redirigir\.php)
RewriteRule ^(.*)$ /index.php/$1 [L]
RewriteRule ^(.*)$ public/maintenance.html [L]
Following rule should work for you:
RewriteEngine on
IndexIgnore *
RewriteCond $1 !^(index\.php|public|images|robots\.txt|favicon\.ico|redirigir\.php)
RewriteRule ^(.*)$ /index.php/$1 [L]
RewriteCond $1 !^(index\.php|public|images|robots\.txt|favicon\.ico|redirigir\.php|customer)
RewriteRule ^(.*)$ public/maintenance.html [L]
First of all you have two lines that capture all URLs and have the [L] last flag. Your second RewriteRuleacts only on the exceptions configured in the first RewriteCond. You need to change like this in order to get your second RewriteRule come into play:
RewriteCond $1 !^(index\.php|public|images|robots\.txt|favicon\.ico|redirigir\.php)
RewriteRule ^(.*)$ public/maintenance.html [L]
Then add your exception URLs to the.htaccess file.
If they are valid directories, you simply add a line to exclude all directories. You need to add the [OR] flag, which means that either RewriteCond has to be true. Without this flag, the rule matches only when both conditions apply.
RewriteCond $1 !^(index\.php|public|images|robots\.txt|favicon\.ico|redirigir\.php) [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ public/maintenance.html [L]
If they are rewritten through the first rewrite rule, you must add another condition on the first rule:
RewriteCond $1 !^(index\.php|public|images|robots\.txt|favicon\.ico|redirigir\.php)
RewriteCond $1 customer/contract/(download|upload)
RewriteRule ^(.*)$ /index.php/$1 [L]
RewriteRule ^(.*)$ public/maintenance.html [L]
Here the first rule will only match your special URLs, and the second rule will match everything else.

combine two .htaccess rewrite files

I have two different .htaccess files each doing different things and when i combine them they won't work together.
the first one allows me to enter www.mydoman.com/test and have it mean www.mydomain.com/index.php?page=test
RewriteRule ^([A-Za-z0-9-_]+)/?$ index.php?subclass=$1 [NC,L]
RewriteRule ^.* index.php [NC,L]
The second file cuts off the extension from .html and .php files so can use www.mydomain.com/about insted of www.mydoman.com/about.php
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /cl_clone
## hide .php extension
# To externally redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L,NC]
## To internally redirect /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [L]
# e.g. example.com/foo will display the contents of example.com/foo.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+)$ $1.html [L,QSA]
Is there a way to allow both of these to work together in one .htaccess file?
You have a redirect rule at the top, and then 2 sets of rules to add either the php or html extensions to the end of the request, if such a file exists. Then your other rule does routing for index.php.
Some things you'll need to work out. You have the rewrite base /cl_clone which doesn't seem like it's going to work at all, in either of the cases, because your URLs don't have cl_clone in the request (e.g. they are simply www.mydomain.com/about, no cl_clone).
So you probably want to remove that.
Otherwise, you can simply add the index.php routing rules at the very bottom of the other rules that you have. You may need to add additional tweaking, perhaps:
RewriteRule ^([A-Za-z0-9-_]+)/?$ index.php?subclass=$1 [NC,L]
RewriteCond %{REQUEST_URI} !index.php
RewriteRule ^.* index.php [NC,L]
Or changing your RewriteBase /cl_clone to RewriteBase /

Resources