After removing .php and adding / file not loading (object not found) - apache

I was trying to remove the .php extension and add a / as normal websites have. Example http://example.com/category/.
I use .htaccess to remove .php. Here is the code:
RewriteEngine On
RewriteBase /
# hide .php extension snippet
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1/ [R,L]
# add a trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !/$
RewriteRule . %{REQUEST_URI}/ [L,R=301]
This code does its task. It removes .php and adds / but the PHP page is now not loading.
This is a screenshot (file name test.php):
How to solve this?

It is because you're missing an internal rule to add .php silently to such redirect URIs.
You can add this rule in the end for that habndling:
RewriteEngine On
RewriteBase /
# hide .php extension snippet
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1/ [R=301,NE,L]
# add a trailing slash if needed
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !/$
RewriteRule . %{REQUEST_URI}/ [L,R=301]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/$ $1.php [L]

After a few research that is actually working in my case is given below.
It removes the .php extension and adds / at the end of the URL.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
Output:
Reference: https://alexcican.com/post/how-to-remove-php-html-htm-extensions-with-htaccess/

Related

How can I use .htaccess to hide extension and prevent user access with extension url?

here is my code for hide .html and .php extension when user view my site, http://example.com/xxx.html to http://example.com/xxx
But I hope to make user when they input http://example.com/xxx.html, they cannnot access and jump to 404 not found.
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# Add trailing slash to url
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/|#(.*))$
RewriteRule ^(.*)$ $1/ [R=301,L]
# Remove .php-extension from url
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^\.]+)/$ $1.php
# Remove .html-extension from url
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^([^\.]+)/$ $1.html
# End of Apache Rewrite Rules
</IfModule>
Anyone have solution?
You can add this as your first rule:
RewriteCond %{THE_REQUEST} \.(?:html|php)\s [NC]
RewriteRule ^ - [R=404,L]
Update
Perhaps this will fix your ErrorDocument problem:
RewriteCond %{THE_REQUEST} \.(?:html|php)\s [NC]
RewriteCond %{REQUEST_URI} !=/error404.html
RewriteRule ^ - [R=404,L]

How to remove php extension and also redirect extensions to no extension form

How can I have this in my htaccess:
/page.php => redirects to /page
/page => shows the page.php
/index => redirects to root
And how to remove trailing slashes from all URLs, specially the root one?
Although, I'm not familiar enough with Apache configs, but I could find these codes:
# To remove .php extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
# To remove trailing slashes
RewriteRule ^(.*)/$ /$1 [L,R=301]
# To redirect /index to root (not sure if it works correctly)
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index.php$ /$1 [R=301,L]
Could you please help me with the scenario and have it in one small code?
Thanks
According to answers, I could solve the problem using the codes below in my .htaccess file:
# To remove .php extension
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ (.*)\.php [NC]
RewriteRule ^ %1 [R=301,L]
# To remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301,L]
# To check whether the file exists then set it back internally
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^.*$ $0.php [L]
# To redirect /index to root
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index.php$ /$1 [R=301,L]
Now, I got a new problem and that is when I browse the files with a trailing slash, it redirects me to somewhere else and occurs a 404 (page not found) response, like this:
http://domain.tld/page/ => http://domain.tld/page/home/user/public_html/domain.tld/page
Also, if I move the second part to the end or even remove it completely, the server sends me a 500 (internal server error) response.
Finally with a little research, I could find the solution for previous problem using this advice:
https://stackoverflow.com/a/27264788/5420319
So, I've changed one of the codes from this:
# To remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301,L]
To this:
# To remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /(.*)/$
RewriteRule ^ /%1 [R=301,L]
And I also moved this part to the top regardless of being effective.
According the the answers and my own research, this would be the final answer:
# To remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /(.*)/$
RewriteRule ^ /%1 [R=301,L]
# To remove .php extension
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ (.*)\.php [NC]
RewriteRule ^ %1 [R=301,L]
# To check whether the file exists then set it back internally
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^.*$ $0.php [L]
# To redirect /index to root
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index.php$ /$1 [R=301,L]
Redirecting page.php to /page:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ /page\.php [NC]
RewriteRule ^ /page [R=301,L]
Now, setting back internally to page.php:
RewriteRule ^page$ /page.php [NC,L]
Remove trailing slashes:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301,L]
Now, checking whether a file for /some/page/foo such that /some/page/foo.php exists:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^.*$ $0.php [L]
A cleaned up and simplified version of the accepted answer is:
# To remove trailing slash
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301,L]
# To remove .php extension
RewriteRule ^(.*)\.php$ $1 [R=301,L]
# To check whether the file exists then set it back internally
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}.php -f
RewriteRule ^.*$ $0.php [L]
Options +FollowSymLinks
RewriteEngine on
AddHandler php5.3-fastcgi php
SetEnv no-gzip dont-vary
RewriteRule ^([a-z]+)$ index.php?page=$1 [QSA,L]
RewriteRule ^([a-z]+)/([a-z0-9]+)$ index.php?page=$1&subpage=$2 [QSA,L]
RewriteRule ^([a-z]+)/([a-z0-9]+)/([a-z0-9]+)$ index.php?page=$1&subpage=$2&module=$3 [QSA,L]
RewriteRule ^([a-z]+)/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)$ index.php?page=$1&subpage=$2&module=$3&submodule=$4 [QSA,L]
You can play with that.

htaccess mod_rewrite: Simplifying URL

I've been having trouble with the following rewrite. I'm certain mod_rewrite is enabled but not sure where I am going wrong.
I'm try to change the following pattern:
/profile/?userid=157&username=FirstL
to:
/profile/FirstL
I've tried many different rules, but the two I felt were the closest to being correct aren't working at all. My current failures below:
RewriteEngine On
RewriteCond %{THE_REQUEST} \ /profile/+\?userid=$([^&\ ]+)&username=$([^&\ ]+)
RewriteRule ^ /%1? [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ /profile/?userid=$1&username=$2 [L,QSA]
 
RewriteEngine On
RewriteRule ^([^/]*)$ /profile/?userid=$1&username=$2 [L]
Full htaccess:
Options +FollowSymLinks -Multiviews
RewriteEngine On
RewriteCond %{THE_REQUEST} \ /profile/+\?userid=$([^&\ ]+)&username=$([^&\ ]+)
RewriteRule ^ /profile/%1/%2? [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^profile/([^/]+)/([^/]+)$ /profile/?userid=$1&username=$2 [L,QSA]
RewriteBase /
DirectorySlash Off
RewriteRule ^admin$ /admin/index.php [L,E=LOOP:1]
RewriteCond %{ENV:REDIRECT_LOOP} !1
RewriteRule ^admin/index.php$ /admin [R=301,L]
# remove .php
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]
#Force non-www:
RewriteCond %{HTTP_HOST} www.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
You're losing the userID part of the URL, so when you try to internally rewrite that back, there's nothing there:
RewriteRule ^([^/]+)$ /profile/?userid=$1&username=$2 [L,QSA]
This rule says the first match is the "userid" and the second match is the "username", and you only have one match, and on top of that, it doesn't even begin with "profile".
You'll need to include the userid somewhere in the URL, otherwise there's no way to extract it.
RewriteEngine On
RewriteCond %{THE_REQUEST} \ /profile/+\?userid=([^&\ ]+)&username=([^&\ ]+)
RewriteRule ^ /profile/%1/%2? [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^profile/([^/]+)/([^/]+)$ /profile/?userid=$1&username=$2 [L,QSA]

force remove .php extension in .htaccess

i know there are many questions like "How do i remove the .php extension, so that /test/ will be /test.php"
but if the user directly goes to test.php it doesnt replace the extension.
So I want to replace the .php it should be /.
here is the part of the .htacces I'm using:
RewriteEngine on
RewriteRule stuff\.php /other_stuff/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^/]+)/$ $1.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
You need to do the check against the actual request instead of the URI (which gets rewritten by other rules). The %{THE_REQUEST} variable doesn't change in the course of the rewrite engine. Try adding these rules right below the RewriteEngine directive:
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /([^/]+)\.php(\?|\ |$)
RewriteRule ^ /%2/ [L,R=301]

Redirect .php to extensionless and make url without .php

I dont really know too much about Rewrite in apache, but there is problem with my .htaccess file.
the original .htaccess is
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9-_.]*)$ /profile.php?id=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
# Redirect non-www to www:
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
# Unless directory, remove trailing slash
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ http://www.domain.com/$1 [R=301,L]
# Redirect external .php requests to extensionless url
RewriteCond %{THE_REQUEST} ^(.+)\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(.+)\.php$ http://www.domain.com/$1 [R=301,L]
# Resolve .php file for extensionless php urls
RewriteRule ^([^/.]+)$ $1.php [L]
ErrorDocument 404 /404.html
The first rewrite is for vanity url, another is redirecting non www to www and after that .php to extension less and redirecting .php file to extension less,
Problem i am facing is, if i request www.domain.com/ttt.php and if ttt doesn't exist then it redirects me to http://www.domain.com/profile?id=ttt.php
Also, i want the rewrite to be for php files not other type, Say if i have ttt.png file and i open www.domain.com/ttt it opens the image rather than showing 404 error.
Similarly happens with other type of files. It opens .txt file first if the names are common.
Thanks for any changes to this, seriously i don't want to mess my site.
This rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9-_.]*)$ /profile.php?id=$1 [L]
Needs to be at the very end.
And this rule:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
Needs the [L] flag and needs to replace RewriteRule ^([^/.]+)$ $1.php [L]. Then you can duplicate this one and replace .php with .png, and .txt and every other extension you want to handle, in the order of preference:
Options +FollowSymLinks -Multiviews
RewriteEngine on
# Redirect non-www to www:
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
# Unless directory, remove trailing slash
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ http://www.domain.com/$1 [R=301,L]
# Redirect external .php requests to extensionless url
RewriteCond %{THE_REQUEST} ^(.+)\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(.+)\.php$ http://www.domain.com/$1 [R=301,L]
# add extension if the php file exists:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
# add extension if the png file exists:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.png -f
RewriteRule ^(.*)$ $1.png [L]
# add extension if the txt file exists:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.txt -f
RewriteRule ^(.*)$ $1.txt [L]
# add extension if the html file exists:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html [L]
# etc.
# finally, route to profile.php if all else fails
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9-_.]*)$ /profile.php?id=$1 [L]
ErrorDocument 404 /404.html
Since you're routing to profile.php, in the profile.php script, you'll need to redirect to /404.html if the id param doesn't exist (meaning the URI that got routed needs to be a 404).