Multiple Vanity URLs with different pages in different directories - php

I am trying to setup my .htaccess file to allow for multiple vanity URLs which is fine, but I'm running into issues with them with the pages being in different directories.
First vanity URL is setup and working fine, which works like this:
example.com/blognumber1 > example.com/inspiration/article.php?id=blognumber1
RewriteBase /inspiration/
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteRule ^(.*)$ article.php?id=$1 [QSA,L]
I am trying to add another one which would work like this:
example.com/supplier/test1 > example.com/profile.php?id=test1
Because the article.php page is in a different directory, I am having problems trying to code it, any help would be appreciated.

Don't use a RewriteBase directive (which applies to the entire file) and make sure the more specific /supplier/test1 rule is first. For example:
RewriteEngine On
# Abort early if a directory or file is requested directly
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# Rewrite "/supplier/<test1>" to "profile.php?id=<test1>"
RewriteRule ^supplier/([^/]*)$ profile.php?id=$1 [QSA,L]
# Rewrite "/<blognumber1>" to "inspiration/article.php?id=<blognumber1>"
RewriteRule ^(.*)$ inspiration/article.php?id=$1 [QSA,L]
Note that the NC flag is not permitted on the RewriteCond directive when used with the filesystem checks -f and -d. If you check your error log you will probably see a stack of warnings.
On the /supplier/test1 rule, it only matches a single path segment after /supplier/, ie. it does not match /supplier/test1/something.
Your existing rule is rather generic as it literally matches anything. Perhaps restrict this to a single path segment also? Or restrict the regex to what constitutes a blognumber.
Optimisation
As a further optimisation you could also abort early if a .php file (or a URL that looks-like a .php file) is requested. Unless you have valid "supplier" or "blog" URLs that end in .php? For example, immediately after the RewriteEngine directive:
# Abort early if any `.php` URL is requested (includes rewritten URLs)
RewriteRule \.php$ - [L]
You can extend this for any URL that looks-like it contains a file extension, which should naturally include your static assets and therefore avoid the filesystem check. For example:
RewriteRule \.\w{2,5}$ - [L]

Related

.htaccess - How to redirect URL to a folder and then to a PHP file

I am setting up a cache system for my blog (not a WordPress) and I want to store the cached files in a posts/ folder, so I don't fill my root folder with post files.
I have a file called post.php that creates these posts files if the slug corresponds to an actual post in a different website (I check this with WordPress REST API). So when I visit mywebsite.com/slug-to-post and this URL doesn't match any of my files on the root level, it fallbacks to post.php using FallbackResource post.php in .htaccess, and post.php uses this slug to create a cached version and stores it, but since there can be thousands of posts, I don't want the files to be stored in the root level, but in posts/name-of-the-file.
So that file would be accessed via mywebsite.com/posts/slug-to-post but for SEO purposes I still want it to be mywebsite.com/slug-to-post.
What should I write in my .htaccess to fallback any unknown file to the posts/ folder, and if the file doesn't exists there, fallback again to post.php, which is stored on root level?
Nothing I've tried has worked so far.
To cache the files I'm using the code present here: https://phppot.com/php/php-cache-for-dynamic-web-pages/
UPDATE: This is my current .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/posts/$1 -f
RewriteRule ^([^/]+\.php)$ /posts/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^[^/]+\.php$ post.php [L]
You are requesting a file of the form /<post-slug>, which either:
Maps to a file of the form /<post-slug>.php in the document root.
OR, maps to a cached version of this file of the form /posts/<post-slug>.php.
Otherwise, the request should fallback to /post.php in the document root.
Try something like the following (using mod_rewrite) in addition to your FallbackResource directive:
# Disable MultiViews
Options -MultiViews
RewriteEngine On
# 1. Check for file in the document root
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^/.]+)$ /$1.php [L]
# 2. Check for cached version in the "/posts" subdirectory
RewriteCond %{DOCUMENT_ROOT}/posts/$1.php -f
RewriteRule ^([^/.]+)$ /posts/$1.php [L]
# 3. Request does not map to a file, so fallback to "/post.php"
FallbackResource /post.php
This does assume that your <post-slug> does not contain dots (.). This makes it easier to avoid conflicts with static resource or create an unnecessary filesystem check after rewriting the request to <post-slug>.php. If the <post-slug> can contain dots then we'll need to alter the RewriteRule pattern and add an additional condition.
NB: MultiViews needs to be disabled for this to work properly (it may already be disabled on your server).
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
Just a few notes on your original rule block.
If you make the RewriteRule pattern more restrictive, rather than matching anything (ie. .*) then you can probably avoid the condition that checks that the request does not map to a filesystem directory. (Is a request for a filesystem directory ever a valid request?)
A literal dot in the RewriteCond TestString (1st argument) does not need to be backslash escaped. This is an "ordinary" string, not a regex.
Note that %{REQUEST_FILENAME}.php is not necessarily the same as the (potentially) rewritten URL $1.php - it will depend on the request and the filesystem (since REQUEST_FILENAME is calculated after the request has been mapped to the filesystem), but since you are allowing anything (ie. .*) then there is potential for error here.
The NC flag is superfluous, since the RewriteRule pattern is not case-sensitive anyway.

Use htaccess to rewrite php extensions and query strings [duplicate]

Yes, I've read the Apache manual and searched here. For some reason I simply cannot get this to work. The closest I've come is having it remove the extension, but it points back to the root directory. I want this to just work in the directory that contains the .htaccess file.
I need to do three things with the .htaccess file.
I need it to remove the .php
a. I have several pages that use tabs and the URL looks like page.php#tab - is this possible?
b. I have one page that uses a session ID appended to the URL to make sure you came from the right place, www.domain.example/download-software.php?abcdefg.
Is this possible? Also in doing this, do I need to remove .php from the links in my header nav include file? Should IE "support" be support?
I would like it to force www before every URL, so it's not domain.example, but www.domain.example/page.
I would like to remove all trailing slashes from pages.
I'll keep looking, trying, etc. Would being in a sub directory cause any issues?
Gumbo's answer in the Stack Overflow question How to hide the .html extension with Apache mod_rewrite should work fine.
Re 1) Change the .html to .php
Re a.) Yup, that's possible, just add #tab to the URL.
Re b.) That's possible using QSA (Query String Append), see below.
This should also work in a sub-directory path:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
Apache mod_rewrite
What you're looking for is mod_rewrite,
Description: Provides a rule-based rewriting engine to rewrite
requested URLs on the fly.
Generally speaking, mod_rewrite works by matching the requested document against specified regular expressions, then performs URL rewrites internally (within the Apache process) or externally (in the clients browser). These rewrites can be as simple as internally translating example.com/foo into a request for example.com/foo/bar.
The Apache docs include a mod_rewrite guide and I think some of the things you want to do are covered in it. Detailed mod_rewrite guide.
Force the www subdomain
I would like it to force "www" before every URL, so its not domain.example but www.domain.example/page
The rewrite guide includes instructions for this under the Canonical Hostname example.
Remove trailing slashes (Part 1)
I would like to remove all trailing slashes from pages
I'm not sure why you would want to do this as the rewrite guide includes an example for the exact opposite, i.e., always including a trailing slash. The docs suggest that removing the trailing slash has great potential for causing issues:
Trailing Slash Problem
Description:
Every webmaster can sing a song about the problem of the trailing
slash on URLs referencing directories. If they are missing, the server
dumps an error, because if you say /~quux/foo instead of /~quux/foo/
then the server searches for a file named foo. And because this file
is a directory it complains. Actually it tries to fix it itself in
most of the cases, but sometimes this mechanism need to be emulated by
you. For instance after you have done a lot of complicated URL
rewritings to CGI scripts etc.
Perhaps you could expand on why you want to remove the trailing slash all the time?
Remove .php extension
I need it to remove the .php
The closest thing to doing this that I can think of is to internally rewrite every request document with a .php extension, i.e., example.com/somepage is instead processed as a request for example.com/somepage.php. Note that proceeding in this manner would would require that each somepage actually exists as somepage.php on the filesystem.
With the right combination of regular expressions this should be possible to some extent. However, I can foresee some possible issues with index pages not being requested correctly and not matching directories correctly.
For example, this will correctly rewrite example.com/test as a request for example.com/test.php:
RewriteEngine on
RewriteRule ^(.*)$ $1.php
But will make example.com fail to load because there is no example.com/.php
I'm going to guess that if you're removing all trailing slashes, then picking a request for a directory index from a request for a filename in the parent directory will become almost impossible. How do you determine a request for the directory 'foobar':
example.com/foobar
from a request for a file called foobar (which is actually foobar.php)
example.com/foobar
It might be possible if you used the RewriteBase directive. But if you do that then this problem gets way more complicated as you're going to require RewriteCond directives to do filesystem level checking if the request maps to a directory or a file.
That said, if you remove your requirement of removing all trailing slashes and instead force-add trailing slashes the "no .php extension" problem becomes a bit more reasonable.
# Turn on the rewrite engine
RewriteEngine on
# If the request doesn't end in .php (Case insensitive) continue processing rules
RewriteCond %{REQUEST_URI} !\.php$ [NC]
# If the request doesn't end in a slash continue processing the rules
RewriteCond %{REQUEST_URI} [^/]$
# Rewrite the request with a .php extension. L means this is the 'Last' rule
RewriteRule ^(.*)$ $1.php [L]
This still isn't perfect -- every request for a file still has .php appended to the request internally. A request for 'hi.txt' will put this in your error logs:
[Tue Oct 26 18:12:52 2010] [error] [client 71.61.190.56] script '/var/www/test.peopleareducks.com/rewrite/hi.txt.php' not found or unable to stat
But there is another option, set the DefaultType and DirectoryIndex directives like this:
DefaultType application/x-httpd-php
DirectoryIndex index.php index.html
Update 2013-11-14 - Fixed the above snippet to incorporate nicorellius's observation
Now requests for hi.txt (and anything else) are successful, requests to example.com/test will return the processed version of test.php, and index.php files will work again.
I must give credit where credit is due for this solution as I found it Michael J. Radwins Blog by searching Google for php no extension apache.
Remove trailing slashes
Some searching for apache remove trailing slashes brought me to some Search Engine Optimization pages. Apparently some Content Management Systems (Drupal in this case) will make content available with and without a trailing slash in URLs, which in the SEO world will cause your site to incur a duplicate content penalty. Source
The solution seems fairly trivial, using mod_rewrite we rewrite on the condition that the requested resource ends in a / and rewrite the URL by sending back the 301 Permanent Redirect HTTP header.
Here's his example which assumes your domain is blamcast.net and allows the the request to optionally be prefixed with www..
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?blamcast\.net$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
Now we're getting somewhere. Lets put it all together and see what it looks like.
Mandatory www., no .php, and no trailing slashes
This assumes the domain is foobar.example and it is running on the standard port 80.
# Process all files as PHP by default
DefaultType application/x-httpd-php
# Fix sub-directory requests by allowing 'index' as a DirectoryIndex value
DirectoryIndex index index.html
# Force the domain to load with the www subdomain prefix
# If the request doesn't start with www...
RewriteCond %{HTTP_HOST} !^www\.foobar\.com [NC]
# And the site name isn't empty
RewriteCond %{HTTP_HOST} !^$
# Finally rewrite the request: end of rules, don't escape the output, and force a 301 redirect
RewriteRule ^/?(.*) http://www.foobar.example/$1 [L,R,NE]
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?foobar\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
The 'R' flag is described in the RewriteRule directive section. Snippet:
redirect|R [=code] (force redirect) Prefix Substitution with
http://thishost[:thisport]/ (which makes the new URL a URI) to force
a external redirection. If no code is given, a HTTP response of 302
(MOVED TEMPORARILY) will be returned.
Final Note
I wasn't able to get the slash removal to work successfully. The redirect ended up giving me infinite redirect loops. After reading the original solution closer I get the impression that the example above works for them because of how their Drupal installation is configured. He mentions specifically:
On a normal Drupal site, with clean URLs enabled, these two addresses
are basically interchangeable
In reference to URLs ending with and without a slash. Furthermore,
Drupal uses a file called .htaccess to tell your web server how to
handle URLs. This is the same file that enables Drupal's clean URL
magic. By adding a simple redirect command to the beginning of your
.htaccess file, you can force the server to automatically remove any
trailing slashes.
In addition to other answers above,
You may also try this to remove .php extensions completely from your file and to avoid infinite loop:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [NC,L]
This code will work in Root/.htaccess,
Be sure to change the RewriteBase if you want to place this to a htaccess file in sub directory.
On Apache 2.4 and later, you can also use the END flag to prevent infinite loop error. The following example works same as the above on Apache 2.4,
RewriteEngine on
RewriteRule ^(.+)\.php$ /$1 [R,L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ /$1.php [NC,END]
The following code works fine for me:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
After changing the parameter AllowOverride from None to All in /etc/apache2/apache2.conf (Debian 8), following this, the .htaccess file just must contain:
Options +MultiViews
AddHandler php5-script php
AddType text/html php
And it was enough to hide .php extension from files
I've ended up with the following working code:
RewriteEngine on
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [NC,L]
Here's a method if you want to do it for just one specific file:
RewriteRule ^about$ about.php [L]
Ref: http://css-tricks.com/snippets/htaccess/remove-file-extention-from-urls/
Try this
The following code will definitely work
RewriteEngine on
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [NC,L]
Not sure why the other answers didn't work for me but this code I found did:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
That is all that is in my htaccess and example.com/page shows example.com/page.php
To remove the .php extension from a PHP file for example yoursite.example/about.php to yoursite.example/about: Open .htaccess (create new one if not exists) file from root of your website, and add the following code.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
To remove the .html extension from a HTML file for example yoursite.example/about.html to yoursite.example/about: Open .htaccess (create new one if not exists) file from root of your website, and add the following code.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Reference: How to Remove PHP Extension from URL
Try this:-
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
I found 100% working Concept for me:
# Options is required by Many Hosting
Options +MultiViews
RewriteEngine on
# For .php & .html URL's:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Use this code in Root of your website .htaccess file like :
offline - wamp\www\YourWebDir
online - public_html/
If it doesn't work correct, then change the settings of your Wamp
Server: 1) Left click WAMP icon 2) Apache 3) Apache Modules 4) Left
click rewrite_module
Here is the code that I used to hide the .php extension from the filename:
## hide .php extension
# To redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L,NC]
Note: R=301 is for permanent redirect and is recommended to use for SEO purpose. However if one wants just a temporary redirect replace it with just R
Try
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [L]
If you're coding in PHP and want to remove .php so you can have a URL like:
http://yourdomain.example/blah -> which points to /blah.php
This is all you need:
<IfModule mod_rewrite.c>
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
If your URL in PHP like http://yourdomain.example/demo.php than comes like
http://yourdomain.example/demo
This is all you need:
create file .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
#RewriteRule ^([^\.]+)$ $1.html [NC,L]
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"
RewriteRule .* - [L,R=404]

Is it possible to rewrite a url upon landing? [duplicate]

Yes, I've read the Apache manual and searched here. For some reason I simply cannot get this to work. The closest I've come is having it remove the extension, but it points back to the root directory. I want this to just work in the directory that contains the .htaccess file.
I need to do three things with the .htaccess file.
I need it to remove the .php
a. I have several pages that use tabs and the URL looks like page.php#tab - is this possible?
b. I have one page that uses a session ID appended to the URL to make sure you came from the right place, www.domain.example/download-software.php?abcdefg.
Is this possible? Also in doing this, do I need to remove .php from the links in my header nav include file? Should IE "support" be support?
I would like it to force www before every URL, so it's not domain.example, but www.domain.example/page.
I would like to remove all trailing slashes from pages.
I'll keep looking, trying, etc. Would being in a sub directory cause any issues?
Gumbo's answer in the Stack Overflow question How to hide the .html extension with Apache mod_rewrite should work fine.
Re 1) Change the .html to .php
Re a.) Yup, that's possible, just add #tab to the URL.
Re b.) That's possible using QSA (Query String Append), see below.
This should also work in a sub-directory path:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
Apache mod_rewrite
What you're looking for is mod_rewrite,
Description: Provides a rule-based rewriting engine to rewrite
requested URLs on the fly.
Generally speaking, mod_rewrite works by matching the requested document against specified regular expressions, then performs URL rewrites internally (within the Apache process) or externally (in the clients browser). These rewrites can be as simple as internally translating example.com/foo into a request for example.com/foo/bar.
The Apache docs include a mod_rewrite guide and I think some of the things you want to do are covered in it. Detailed mod_rewrite guide.
Force the www subdomain
I would like it to force "www" before every URL, so its not domain.example but www.domain.example/page
The rewrite guide includes instructions for this under the Canonical Hostname example.
Remove trailing slashes (Part 1)
I would like to remove all trailing slashes from pages
I'm not sure why you would want to do this as the rewrite guide includes an example for the exact opposite, i.e., always including a trailing slash. The docs suggest that removing the trailing slash has great potential for causing issues:
Trailing Slash Problem
Description:
Every webmaster can sing a song about the problem of the trailing
slash on URLs referencing directories. If they are missing, the server
dumps an error, because if you say /~quux/foo instead of /~quux/foo/
then the server searches for a file named foo. And because this file
is a directory it complains. Actually it tries to fix it itself in
most of the cases, but sometimes this mechanism need to be emulated by
you. For instance after you have done a lot of complicated URL
rewritings to CGI scripts etc.
Perhaps you could expand on why you want to remove the trailing slash all the time?
Remove .php extension
I need it to remove the .php
The closest thing to doing this that I can think of is to internally rewrite every request document with a .php extension, i.e., example.com/somepage is instead processed as a request for example.com/somepage.php. Note that proceeding in this manner would would require that each somepage actually exists as somepage.php on the filesystem.
With the right combination of regular expressions this should be possible to some extent. However, I can foresee some possible issues with index pages not being requested correctly and not matching directories correctly.
For example, this will correctly rewrite example.com/test as a request for example.com/test.php:
RewriteEngine on
RewriteRule ^(.*)$ $1.php
But will make example.com fail to load because there is no example.com/.php
I'm going to guess that if you're removing all trailing slashes, then picking a request for a directory index from a request for a filename in the parent directory will become almost impossible. How do you determine a request for the directory 'foobar':
example.com/foobar
from a request for a file called foobar (which is actually foobar.php)
example.com/foobar
It might be possible if you used the RewriteBase directive. But if you do that then this problem gets way more complicated as you're going to require RewriteCond directives to do filesystem level checking if the request maps to a directory or a file.
That said, if you remove your requirement of removing all trailing slashes and instead force-add trailing slashes the "no .php extension" problem becomes a bit more reasonable.
# Turn on the rewrite engine
RewriteEngine on
# If the request doesn't end in .php (Case insensitive) continue processing rules
RewriteCond %{REQUEST_URI} !\.php$ [NC]
# If the request doesn't end in a slash continue processing the rules
RewriteCond %{REQUEST_URI} [^/]$
# Rewrite the request with a .php extension. L means this is the 'Last' rule
RewriteRule ^(.*)$ $1.php [L]
This still isn't perfect -- every request for a file still has .php appended to the request internally. A request for 'hi.txt' will put this in your error logs:
[Tue Oct 26 18:12:52 2010] [error] [client 71.61.190.56] script '/var/www/test.peopleareducks.com/rewrite/hi.txt.php' not found or unable to stat
But there is another option, set the DefaultType and DirectoryIndex directives like this:
DefaultType application/x-httpd-php
DirectoryIndex index.php index.html
Update 2013-11-14 - Fixed the above snippet to incorporate nicorellius's observation
Now requests for hi.txt (and anything else) are successful, requests to example.com/test will return the processed version of test.php, and index.php files will work again.
I must give credit where credit is due for this solution as I found it Michael J. Radwins Blog by searching Google for php no extension apache.
Remove trailing slashes
Some searching for apache remove trailing slashes brought me to some Search Engine Optimization pages. Apparently some Content Management Systems (Drupal in this case) will make content available with and without a trailing slash in URLs, which in the SEO world will cause your site to incur a duplicate content penalty. Source
The solution seems fairly trivial, using mod_rewrite we rewrite on the condition that the requested resource ends in a / and rewrite the URL by sending back the 301 Permanent Redirect HTTP header.
Here's his example which assumes your domain is blamcast.net and allows the the request to optionally be prefixed with www..
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?blamcast\.net$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
Now we're getting somewhere. Lets put it all together and see what it looks like.
Mandatory www., no .php, and no trailing slashes
This assumes the domain is foobar.example and it is running on the standard port 80.
# Process all files as PHP by default
DefaultType application/x-httpd-php
# Fix sub-directory requests by allowing 'index' as a DirectoryIndex value
DirectoryIndex index index.html
# Force the domain to load with the www subdomain prefix
# If the request doesn't start with www...
RewriteCond %{HTTP_HOST} !^www\.foobar\.com [NC]
# And the site name isn't empty
RewriteCond %{HTTP_HOST} !^$
# Finally rewrite the request: end of rules, don't escape the output, and force a 301 redirect
RewriteRule ^/?(.*) http://www.foobar.example/$1 [L,R,NE]
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?foobar\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
The 'R' flag is described in the RewriteRule directive section. Snippet:
redirect|R [=code] (force redirect) Prefix Substitution with
http://thishost[:thisport]/ (which makes the new URL a URI) to force
a external redirection. If no code is given, a HTTP response of 302
(MOVED TEMPORARILY) will be returned.
Final Note
I wasn't able to get the slash removal to work successfully. The redirect ended up giving me infinite redirect loops. After reading the original solution closer I get the impression that the example above works for them because of how their Drupal installation is configured. He mentions specifically:
On a normal Drupal site, with clean URLs enabled, these two addresses
are basically interchangeable
In reference to URLs ending with and without a slash. Furthermore,
Drupal uses a file called .htaccess to tell your web server how to
handle URLs. This is the same file that enables Drupal's clean URL
magic. By adding a simple redirect command to the beginning of your
.htaccess file, you can force the server to automatically remove any
trailing slashes.
In addition to other answers above,
You may also try this to remove .php extensions completely from your file and to avoid infinite loop:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [NC,L]
This code will work in Root/.htaccess,
Be sure to change the RewriteBase if you want to place this to a htaccess file in sub directory.
On Apache 2.4 and later, you can also use the END flag to prevent infinite loop error. The following example works same as the above on Apache 2.4,
RewriteEngine on
RewriteRule ^(.+)\.php$ /$1 [R,L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ /$1.php [NC,END]
The following code works fine for me:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
After changing the parameter AllowOverride from None to All in /etc/apache2/apache2.conf (Debian 8), following this, the .htaccess file just must contain:
Options +MultiViews
AddHandler php5-script php
AddType text/html php
And it was enough to hide .php extension from files
I've ended up with the following working code:
RewriteEngine on
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [NC,L]
Here's a method if you want to do it for just one specific file:
RewriteRule ^about$ about.php [L]
Ref: http://css-tricks.com/snippets/htaccess/remove-file-extention-from-urls/
Try this
The following code will definitely work
RewriteEngine on
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [NC,L]
Not sure why the other answers didn't work for me but this code I found did:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
That is all that is in my htaccess and example.com/page shows example.com/page.php
To remove the .php extension from a PHP file for example yoursite.example/about.php to yoursite.example/about: Open .htaccess (create new one if not exists) file from root of your website, and add the following code.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
To remove the .html extension from a HTML file for example yoursite.example/about.html to yoursite.example/about: Open .htaccess (create new one if not exists) file from root of your website, and add the following code.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Reference: How to Remove PHP Extension from URL
Try this:-
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
I found 100% working Concept for me:
# Options is required by Many Hosting
Options +MultiViews
RewriteEngine on
# For .php & .html URL's:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Use this code in Root of your website .htaccess file like :
offline - wamp\www\YourWebDir
online - public_html/
If it doesn't work correct, then change the settings of your Wamp
Server: 1) Left click WAMP icon 2) Apache 3) Apache Modules 4) Left
click rewrite_module
Here is the code that I used to hide the .php extension from the filename:
## hide .php extension
# To redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L,NC]
Note: R=301 is for permanent redirect and is recommended to use for SEO purpose. However if one wants just a temporary redirect replace it with just R
Try
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [L]
If you're coding in PHP and want to remove .php so you can have a URL like:
http://yourdomain.example/blah -> which points to /blah.php
This is all you need:
<IfModule mod_rewrite.c>
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
If your URL in PHP like http://yourdomain.example/demo.php than comes like
http://yourdomain.example/demo
This is all you need:
create file .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
#RewriteRule ^([^\.]+)$ $1.html [NC,L]
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"
RewriteRule .* - [L,R=404]

Remove PHP file extension AND trailing slash using MAMP [duplicate]

Yes, I've read the Apache manual and searched here. For some reason I simply cannot get this to work. The closest I've come is having it remove the extension, but it points back to the root directory. I want this to just work in the directory that contains the .htaccess file.
I need to do three things with the .htaccess file.
I need it to remove the .php
a. I have several pages that use tabs and the URL looks like page.php#tab - is this possible?
b. I have one page that uses a session ID appended to the URL to make sure you came from the right place, www.domain.example/download-software.php?abcdefg.
Is this possible? Also in doing this, do I need to remove .php from the links in my header nav include file? Should IE "support" be support?
I would like it to force www before every URL, so it's not domain.example, but www.domain.example/page.
I would like to remove all trailing slashes from pages.
I'll keep looking, trying, etc. Would being in a sub directory cause any issues?
Gumbo's answer in the Stack Overflow question How to hide the .html extension with Apache mod_rewrite should work fine.
Re 1) Change the .html to .php
Re a.) Yup, that's possible, just add #tab to the URL.
Re b.) That's possible using QSA (Query String Append), see below.
This should also work in a sub-directory path:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
Apache mod_rewrite
What you're looking for is mod_rewrite,
Description: Provides a rule-based rewriting engine to rewrite
requested URLs on the fly.
Generally speaking, mod_rewrite works by matching the requested document against specified regular expressions, then performs URL rewrites internally (within the Apache process) or externally (in the clients browser). These rewrites can be as simple as internally translating example.com/foo into a request for example.com/foo/bar.
The Apache docs include a mod_rewrite guide and I think some of the things you want to do are covered in it. Detailed mod_rewrite guide.
Force the www subdomain
I would like it to force "www" before every URL, so its not domain.example but www.domain.example/page
The rewrite guide includes instructions for this under the Canonical Hostname example.
Remove trailing slashes (Part 1)
I would like to remove all trailing slashes from pages
I'm not sure why you would want to do this as the rewrite guide includes an example for the exact opposite, i.e., always including a trailing slash. The docs suggest that removing the trailing slash has great potential for causing issues:
Trailing Slash Problem
Description:
Every webmaster can sing a song about the problem of the trailing
slash on URLs referencing directories. If they are missing, the server
dumps an error, because if you say /~quux/foo instead of /~quux/foo/
then the server searches for a file named foo. And because this file
is a directory it complains. Actually it tries to fix it itself in
most of the cases, but sometimes this mechanism need to be emulated by
you. For instance after you have done a lot of complicated URL
rewritings to CGI scripts etc.
Perhaps you could expand on why you want to remove the trailing slash all the time?
Remove .php extension
I need it to remove the .php
The closest thing to doing this that I can think of is to internally rewrite every request document with a .php extension, i.e., example.com/somepage is instead processed as a request for example.com/somepage.php. Note that proceeding in this manner would would require that each somepage actually exists as somepage.php on the filesystem.
With the right combination of regular expressions this should be possible to some extent. However, I can foresee some possible issues with index pages not being requested correctly and not matching directories correctly.
For example, this will correctly rewrite example.com/test as a request for example.com/test.php:
RewriteEngine on
RewriteRule ^(.*)$ $1.php
But will make example.com fail to load because there is no example.com/.php
I'm going to guess that if you're removing all trailing slashes, then picking a request for a directory index from a request for a filename in the parent directory will become almost impossible. How do you determine a request for the directory 'foobar':
example.com/foobar
from a request for a file called foobar (which is actually foobar.php)
example.com/foobar
It might be possible if you used the RewriteBase directive. But if you do that then this problem gets way more complicated as you're going to require RewriteCond directives to do filesystem level checking if the request maps to a directory or a file.
That said, if you remove your requirement of removing all trailing slashes and instead force-add trailing slashes the "no .php extension" problem becomes a bit more reasonable.
# Turn on the rewrite engine
RewriteEngine on
# If the request doesn't end in .php (Case insensitive) continue processing rules
RewriteCond %{REQUEST_URI} !\.php$ [NC]
# If the request doesn't end in a slash continue processing the rules
RewriteCond %{REQUEST_URI} [^/]$
# Rewrite the request with a .php extension. L means this is the 'Last' rule
RewriteRule ^(.*)$ $1.php [L]
This still isn't perfect -- every request for a file still has .php appended to the request internally. A request for 'hi.txt' will put this in your error logs:
[Tue Oct 26 18:12:52 2010] [error] [client 71.61.190.56] script '/var/www/test.peopleareducks.com/rewrite/hi.txt.php' not found or unable to stat
But there is another option, set the DefaultType and DirectoryIndex directives like this:
DefaultType application/x-httpd-php
DirectoryIndex index.php index.html
Update 2013-11-14 - Fixed the above snippet to incorporate nicorellius's observation
Now requests for hi.txt (and anything else) are successful, requests to example.com/test will return the processed version of test.php, and index.php files will work again.
I must give credit where credit is due for this solution as I found it Michael J. Radwins Blog by searching Google for php no extension apache.
Remove trailing slashes
Some searching for apache remove trailing slashes brought me to some Search Engine Optimization pages. Apparently some Content Management Systems (Drupal in this case) will make content available with and without a trailing slash in URLs, which in the SEO world will cause your site to incur a duplicate content penalty. Source
The solution seems fairly trivial, using mod_rewrite we rewrite on the condition that the requested resource ends in a / and rewrite the URL by sending back the 301 Permanent Redirect HTTP header.
Here's his example which assumes your domain is blamcast.net and allows the the request to optionally be prefixed with www..
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?blamcast\.net$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
Now we're getting somewhere. Lets put it all together and see what it looks like.
Mandatory www., no .php, and no trailing slashes
This assumes the domain is foobar.example and it is running on the standard port 80.
# Process all files as PHP by default
DefaultType application/x-httpd-php
# Fix sub-directory requests by allowing 'index' as a DirectoryIndex value
DirectoryIndex index index.html
# Force the domain to load with the www subdomain prefix
# If the request doesn't start with www...
RewriteCond %{HTTP_HOST} !^www\.foobar\.com [NC]
# And the site name isn't empty
RewriteCond %{HTTP_HOST} !^$
# Finally rewrite the request: end of rules, don't escape the output, and force a 301 redirect
RewriteRule ^/?(.*) http://www.foobar.example/$1 [L,R,NE]
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?foobar\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
The 'R' flag is described in the RewriteRule directive section. Snippet:
redirect|R [=code] (force redirect) Prefix Substitution with
http://thishost[:thisport]/ (which makes the new URL a URI) to force
a external redirection. If no code is given, a HTTP response of 302
(MOVED TEMPORARILY) will be returned.
Final Note
I wasn't able to get the slash removal to work successfully. The redirect ended up giving me infinite redirect loops. After reading the original solution closer I get the impression that the example above works for them because of how their Drupal installation is configured. He mentions specifically:
On a normal Drupal site, with clean URLs enabled, these two addresses
are basically interchangeable
In reference to URLs ending with and without a slash. Furthermore,
Drupal uses a file called .htaccess to tell your web server how to
handle URLs. This is the same file that enables Drupal's clean URL
magic. By adding a simple redirect command to the beginning of your
.htaccess file, you can force the server to automatically remove any
trailing slashes.
In addition to other answers above,
You may also try this to remove .php extensions completely from your file and to avoid infinite loop:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [NC,L]
This code will work in Root/.htaccess,
Be sure to change the RewriteBase if you want to place this to a htaccess file in sub directory.
On Apache 2.4 and later, you can also use the END flag to prevent infinite loop error. The following example works same as the above on Apache 2.4,
RewriteEngine on
RewriteRule ^(.+)\.php$ /$1 [R,L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ /$1.php [NC,END]
The following code works fine for me:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
After changing the parameter AllowOverride from None to All in /etc/apache2/apache2.conf (Debian 8), following this, the .htaccess file just must contain:
Options +MultiViews
AddHandler php5-script php
AddType text/html php
And it was enough to hide .php extension from files
I've ended up with the following working code:
RewriteEngine on
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [NC,L]
Here's a method if you want to do it for just one specific file:
RewriteRule ^about$ about.php [L]
Ref: http://css-tricks.com/snippets/htaccess/remove-file-extention-from-urls/
Try this
The following code will definitely work
RewriteEngine on
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [NC,L]
Not sure why the other answers didn't work for me but this code I found did:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
That is all that is in my htaccess and example.com/page shows example.com/page.php
To remove the .php extension from a PHP file for example yoursite.example/about.php to yoursite.example/about: Open .htaccess (create new one if not exists) file from root of your website, and add the following code.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
To remove the .html extension from a HTML file for example yoursite.example/about.html to yoursite.example/about: Open .htaccess (create new one if not exists) file from root of your website, and add the following code.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Reference: How to Remove PHP Extension from URL
Try this:-
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
I found 100% working Concept for me:
# Options is required by Many Hosting
Options +MultiViews
RewriteEngine on
# For .php & .html URL's:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Use this code in Root of your website .htaccess file like :
offline - wamp\www\YourWebDir
online - public_html/
If it doesn't work correct, then change the settings of your Wamp
Server: 1) Left click WAMP icon 2) Apache 3) Apache Modules 4) Left
click rewrite_module
Here is the code that I used to hide the .php extension from the filename:
## hide .php extension
# To redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L,NC]
Note: R=301 is for permanent redirect and is recommended to use for SEO purpose. However if one wants just a temporary redirect replace it with just R
Try
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [L]
If you're coding in PHP and want to remove .php so you can have a URL like:
http://yourdomain.example/blah -> which points to /blah.php
This is all you need:
<IfModule mod_rewrite.c>
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
If your URL in PHP like http://yourdomain.example/demo.php than comes like
http://yourdomain.example/demo
This is all you need:
create file .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
#RewriteRule ^([^\.]+)$ $1.html [NC,L]
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"
RewriteRule .* - [L,R=404]

.htaccess rewrite all URLs, even if path

I've made some PHP code that will direct the user based on the URL, and I've found some code for htaccess that gives the URL to the index page which lets my code work. However, it's also technically revealing what is a file/folder and what isn't.
If I go to website.com/somethingrandom/somethingelse, I'll get a 404 error, whereas going to website.com/cache/private will say forbidden.
How would I edit it so that it will act like no files exist, aside from a few select file types, such as images, css, and js files?
Here is the code as it currently stands:
RewriteBase /
RewriteEngine On
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-f
# This rule converts your flat link to a query
RewriteRule ^(.*)$ index.php?_page_location=$1 [L,NC,NE]
Have your rules like this:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L,NC]
# add trailing slash to directories
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301,NE]
# If the request is not for known file types
RewriteCond %{REQUEST_URI} !\.(?:jpe?g|gif|php|bmp|png|ico|tiff|css|js)$ [NC]
# This rule converts your flat link to a query
RewriteRule .* index.php?_page_location=$0 [L,QSA]
If you want to hide some file or directory, i.e. appear it as not existant, you might redirect with the R|redirect flag
RewriteRule ^cache/private - [R=404,L]
This tells the client, there is no such file named cache/private (404). Beware though, that this is for all clients, even yourself.
To restrict this, you must prefix the rule with some RewriteCond or wrap it in some conditional statement like If or similar.
If you want to hide all files, use a "broader" regular expression, like
RewriteRule ^ - [R=404,L]
This will return a "Not found" for all of your website's URLs. You can also give a set of URLs, like in this
RewriteRule ^(?:cache/private|secrets|database) - [R=404,L]
which will hide everything below
cache/private
secrets
database
See Apache - Regular Expressions and http://www.regular-expressions.info/ for details on how to customize your own pattern.

Categories