I have made this .htaccess file over the last hour through searching, copy and pasting etc.
It does work how I want it to.
However I do not understand it.
Could someone please put it down step by step what is happening here in layman's terms for me.
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^/?(.*)$ /$1.php [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^\ ]+)\.php
RewriteRule ^/?(.*)\.php$ /$1 [L,R=301]
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index.php$ /$1 [R=301,L]
And if there are any tips please throw them in there.
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [L,R=301]
^www\.example\.com$
The anchors ^$
mean this is the complete string in HTTP_HOST
, nothing before or after. Therefore, if the domain name passed with the request matches www.example.com
exactly, the entire URI (.*)
is redirected to example.com
, thereby stripping off the www.
from the front.
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^/?(.*)$ /$1.php [L]
A -f
flag to RewriteCond
tests if the first argument is a file that actually exists. In this case, it tests for the value of REQUEST_FILENAME
, which would be the last part (file
) of a URI like example.com/directory/file
exists as a PHP file, by adding a .php
extension onto the tested argument.
So, if file.php
actually exists, the request for the non-existent file
is here rewritten silently into its corresponding PHP file with $1.php
. So if /directory/notexists
did not have a corresponding directory/notexists.php
file, it would not be rewritten.
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^\ ]+)\.php
RewriteRule ^/?(.*)\.php$ /$1 [L,R=301]
THE_REQUEST
contains the complete GET/POST
request the browser originally sent, like GET /index.php
. So what has been matched here is similar to the previous block.
^[A-Z]{3,9}
first matches the verb GET
or POST
, etc. but doesn't capture it for reuse/([^\ ]+)
then captures everything following /
and up to the next whitespace, like the index
in GET /index.php
.\.php
is literally matchedOk, then the following RewriteRule
takes that index
captured into %1
with the above condition, and actually redirects the browser to remove the .php
extension so the browser's ending URL looks like /index
.
In other words, if the browser requests /directory/file.php
with the .php
extension, it redirects the user to /directory/file
to strip off the .php
.
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index.php$ /$1 [R=301,L]
And this one matches anything containing /index
in the original request, but it need not be at the start of the URI. In other words, /directory/index
would match, as would /directory/subdir/index.php
. No matter what it matches, it is redirected to whatever comes before the index part. Let's break it down:
^(.*)
matches whatever comes at the start into $1
index.php
.. comes after whatever was matched aboveThat is then redirected just to the $1
component, so a URL like /directory/subdir/index.php
if directly requested by the browser, would be redirected to point to the cleaner URL: /directory/subdir/
without the index.php
appearing in the address bar.
Added in-line comments to your .htaccess
code.
# If URL contains "www."
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
# remove it for ALL request
RewriteRule ^(.*)$ http://example.com/$1 [L,R=301]
# If adding ".php" to the URL points to a file
RewriteCond %{REQUEST_FILENAME}\.php -f
# Serve the PHP file
RewriteRule ^/?(.*)$ /$1.php [L]
# If a URL request contains ".php"
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^\ ]+)\.php
# Redirect to the same URL but without ".php"
RewriteRule ^/?(.*)\.php$ /$1 [L,R=301]
# If the request points to index.php
RewriteCond %{THE_REQUEST} ^.*/index
# Remove and redirect to "/"
RewriteRule ^(.*)index.php$ /$1 [R=301,L]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With