Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explain htaccess rules?

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.

like image 786
user2251919 Avatar asked Mar 23 '23 18:03

user2251919


2 Answers

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
  • the /([^\ ]+) then captures everything following / and up to the next whitespace, like the index in GET /index.php.
  • The \.php is literally matched

Ok, 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 above

That 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.

like image 52
Michael Berkowski Avatar answered Mar 31 '23 18:03

Michael Berkowski


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]
like image 45
Ravi K Thapliyal Avatar answered Mar 31 '23 17:03

Ravi K Thapliyal