Require file extension in .htaccess - php

My website is redirecting mywebsite.com/news to mywebsite.com/news.php but I don't want it.
I need it to redirect mywebsite.com/news to mywebsite.com/index.php?param=news
I changed my .htaccess file and the file does work correctly for other words, like this:
mywebsite.com/hello redirects to: mywebsite.com/index.php?param=hello
I have a news.php file in my root folder, but I don't want mywebsite.com/news to redirect to mywebsite.com/news.php
I hope you understand what I mean...
This is my .htaccess file:
Options -Indexes
# pass the default character set
AddDefaultCharset utf-8
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^([\s\S]+)$ index.php?param=$1 [L,QSA,NC,NE]
What changes should I make to solve this?
Any helps, comments, suggestions is appreciated.

Change your Options line to:
Options +FollowSymLinks -MultiViews
The effect of MultiViews is as follows: if the server receives a
request for /some/dir/foo, if /some/dir has MultiViews enabled, and
/some/dir/foo does not exist, then the server reads the directory
looking for files named foo.*, and effectively fakes up a type map
which names all those files, assigning them the same media types and
content-encodings it would have if the client had asked for one of
them by name. It then chooses the best match to the client's
requirements.
https://httpd.apache.org/docs/current/content-negotiation.html
You also can remove .php extension with:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]

Related

.htaccess is causing 403 on one link only

Bit of an odd one and I feel it must be answered but I can't seem to find it.
I have the following in my .htaccess file on a custom PHP site (NOT WORDPRESS):
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(contact|gallery|links)$ $1.php [L]
I cannot work out why "gallery" only is giving me a 403.
example.com/links
example.com/contact
Both work as expected and go to the desired pages. However
example.com/gallery
Redirects to
example.com/gallery/
And throws the 403 Forbidden error
gallery.php is a page and can be accessed from the same URL
There's nothing on gallery.php to redirect or check a query string or compare the URI. I cannot understand it.
Really flying blind on .htaccess stuff (always have), so any help greatly appreciated. What am I doing wrong?!
Also, tested it on https://htaccess.madewithlove.com/ and it said my work was correct, so really don't understand what it's finding incorrect. Why does it think gallery is a subfolder, not a URL?
And I have JUST realised, I do actually have a gallery folder, so if anyone can tell me how to use the htaccess to access the page and not the folder, I'd greatly appreciate it! If it helps, there's a .htaccess in the gallery folder to prevent direct access to images:
Options -Indexes
Options -ExecCGI
# AddHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi
<Files ^(*.jpeg|*.jpg)>
order deny,allow
deny from all
</Files>
<FilesMatch "\.(jpe?g)$">
order allow,deny
allow from all
</FilesMatch>
Would they be conflicting?
Since gallery is a physical directory, you will need to set DirectorySlash Off in order to prevent mod_dir appending the trailing slash via a 301 external redirect. (This redirect gets cached persistently by the browser, so you will need to clear your browser cache before continuing.)
Note, however, that when disabling the DirectorySlash, you must also ensure that Options -Indexes is also set to prevent mod_autoindex from generating directory listings when the trailing slash is omitted from a directory, since a DirectoryIndex document in that directory will no longer prevent the directory listing being generated. See the security warning under the DirectorySlash directive in the Apache Docs.
You may also need to set RewriteOptions AllowNoSlash to allow mod_rewrite to match directories that have no trailing slash.
You then need to modify your existing rule...
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(contact|gallery|links)$ $1.php [L]
Remove the first two RewriteCond directives. They aren't required since you are wanting to rewrite 3 specific URLs. If any of the conditions fail then the rewrite does not occur.
If contact, gallery or links happen to exist as physical files (very unlikely) or directories (gallery is a directory it seems) then the rewrite does not occur.
Summary
DirectorySlash Off
Options +FollowSymlinks -Indexes
RewriteEngine On
RewriteOptions AllowNoSlash
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(contact|gallery|links)$ $1.php [L]

How to forward the HTTP_REFERER to a page from htaccess?

When someone hits my site root folder (www.myDomain.com) and the Index.php page gets it after that, how can I forward HTTP_REFERER to the Index.php page so I can record it?
I have this but No Joy.
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^mydomain.com [NC]
RewriteRule ^/?index.php?%{HTTP_REFERER}$ mydomain.com/ [L,R]
Thanks
Make sure apache mod_rewrite is enabled. Then redirect with:
<IfModule mod_rewrite.c>
# Make sure url's can be rewritten.
RewriteEngine on
# Redirect requests that are not files or directories to index.php.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
</IfModule>
This is how most CMS's do it. this does mean if they write the direct path to a file they will see that file. So you will want to precede this with something like:
# Prevent direct access to these file types.
<FilesMatch "\.(sql|md|sh|scss|rb|conf|rc|tpl(\.php)?|lib(\.php)?|wig(\.php)?|pg(\.php)?|reg(\.php)?|db(\.php)?)$">
Require all denied
</FilesMatch>
This means that they can not access the file extensions listed above. You can replace the last few with just rc|php but I allow access to .php files not proceeded with .lib so I can do scripts protected by browser authentication for debugging and silver bullet database repairs.
You must also have something like this in your apache config that allows the .htaccess to be read in your sites directory.
<Directory "C:/Sites">
AllowOverride All
</Directory>

PHP URL Rewrite - No getting Query String Parameter

I am working on a site and learning PHP at the same time so it is relatively new to me. I am working on URL rewrite currently, however, I am not getting the desired result.
I am trying to change: example.com/CMS/listing?id=1 into example.com/CMS/listing/1.
Using the .htaccess file held in the root of the files, I have the following:
RewriteEngine On
RewriteBase /
RewriteRule CMS/listing/([0-9]+) CMS/listing.php?id=$1
And on the site, I have a simple echo function which gets the query string param for id. When I navigate to example.com/CMS/listing?id=1 the function displays 1, however, when I go to example.com/CMS/listing/1 it does not show anything. Is there something I'm missing or doing wrong?
# Get QString Param
$id = $_GET["id"];
echo $id;
Footnote
.htaccess is held at the root, and listing.php is within a folder called CMS.
It looks like you have a conflict with MultiViews. You should disable MultiViews at the top of your .htaccess file:
Options -MultiViews
If MultiViews is enabled then when you request /CMS/listing/1, mod_negotiation will map the request to /CMS/listing.php (appending the file extension, without any URL parameter) before your mod_rewrite directive is able to process the request. (/1 is seen as additional pathname information or PATH_INFO on the URL.)
A URL like /CMS/listing?id=1 (without the file extension) will only work if MultiViews is enabled. In this case, the query string is already present on the URL.
You could also redirect all traffic through to index.php and handle it all in PHP. That is how other CMS' and framework usually do it.
This is the Laravel approach - you don't have to do it this way, but later on when you want to do custom urls on news post or any other this, you have to setup new rules. This way you can just add them to the database and create some kind off route handler. If you want to keeps it simple you could then just create a table in the database where you store urls and a field for the file to be called.
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

.htaccess redirects to a template selection php file

How would I configure my .htaccess file if I want all requests to always load a core template selection file. I believe this could be good for a few reasons the first of which being security. Only if my php template selection code flags a file as safe for display will it display. Also, it allows me to build some interesting cms functionality like requiring a php metadata array in order to load the template file. How could I accomplish this?
Also, do you think it is practical to choose this method over others?
You can use this rule in your root .htaccess to make core/template.php your front controller:
RewriteEngine on
RewriteBase /
RewriteRule ^core/template\.php$ - [L,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . core/template.php [L]
EDIT: If you want even real files to be routed to same controller use last rule as:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(jpe?g|ico|gif|bmp|png|tiff|css|js)$ core/template.php [L,NC]
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteRule ^(.*)$ /index.php
</IfModule>
Make sure that inside the httpd.conf this line isn't commented:
LoadModule rewrite_module modules/mod_rewrite.so
(It should be without the '#' at the beginning)
And this is my directory tag (I'm using wamp but it should be the same, and of course restart the apache server if you changed something there)
<Directory />
Options FollowSymLinks
AllowOverride All
Order deny,allow
Allow from all
</Directory>

Htaccess, Directory-Style not rewriting to query-style

I have a very basic htaccess, attempting to convert directory-style to query style.
i.e.
a. /public_html/main/folder1/folder2 ... etc
b. /public_html/main.php?1=folder1&1=folder2
No matter what regex I try, to matter what rewrite rule I try - I can't make any progress on this problem.
I've searched the web, many times so far. I've tried 10 different 'recommended' solutions found in other forums.
I don't know where else to look.
Here's my current htaccess:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^public_html/([A-Za-z0-9]+)/([0-9]+)/?$ main.php?name=$1&page=$2 [NC]
Here's my httpd.conf Htaccess directives.
(Directory "/Users/admin/Sites")
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
(/Directory)
(Directory "/Users/admin/Sites/MFCS/V3/public_html/mfcs/public_html")
AllowOverride All
(/Directory)
I replaced the greater than / less than on the directory tags for this example.
the httpd.conf does have the proper tags in it.
Give this a try:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^/main/(.*)/(.*)/?$ /main.php?name=$1&page=$2 [L]
This will redirect requests to:
http://www.example.com/main/folder1/folder2
To:
http://www.example.com/main.php?name=folder1&page=folder2
If this is not the outcome your looking for please provide a sample before and after. On another note did you make sure to enable mod_rewrite? I also removed the public_html from the URI because it's normally not visible to the public.

Categories