im going to ask a really simple question. i dont want my link to show this when i run my page :
http://localhost/example/assets/gallery.php
what i want is :
http://localhost/example/assets/
so how to do it in .htaccess file ?
i would really appreciate it if you can help because im so confused after reading forums .
my htaccess is like this right now but you know it only helps to remove extension :
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
How to make assets/gallery.php -> assets/
In the assets folder make a .htaccess file
Paste in this code :
DirectoryIndex gallery.php
This code changes the Directory Index (like a index.php file) to the gallery.php file meaning gallery.php is now like the index.php file.
The DirectoryIndex method that #RyanTheGhost suggests in his answer should have worked for the specific example you posted (where you request a directory and are serving a file from within that directory). However, the mod_rewrite directives you currently have in the document root1 will conflict with any requests for directories2 (although the DirectoryIndex should take priority).
However, the DirectoryIndex method is not very practical if you have many such files. And if you are not requesting a directory then this method naturally won't work anyway.
You could instead rewrite the URL using mod_rewrite in your existing .htaccess file, before your current directives.
1 I'm assuming your .htaccess file is in the document root.
For example:
# Rewrite "/example/assets/" to "/example/assets/gallery.php"
RewriteRule ^example/assets/$ example/assets/gallery.php [L]
Or, to avoid repitition:
# Rewrite "/example/assets/" to "/example/assets/gallery.php"
RewriteRule ^example/assets/$ $0gallery.php [L]
Where the $0 backreference contains the entire URL-path that is matched by the RewriteRule pattern. ie. example/assets/ in this case. NB: There is no slash prefix on the RewriteRule pattern or the substitution string.
Note that since you are requesting a directory (ie. /example/assets/) you need to ensure there is no DirectoryIndex document in that directory (eg. index.html or index.php), otherwise this will be served (by mod_dir) instead, overriding your internal rewrite above.
2 Your current directives that append the .php extension are arguably incorrect:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
This rule appends the .php extension to any request that does not map to a physical file, even if the file with a .php extension does not exist either. This can result in the incorrect URL being reported back to the user in the 404 error document (depending on how this is implemented). For example, the default Apache 404 error document will report that /foo.php does not exist, when the user requested /foo.
This rule will also rewrite directories (since they are "not files") which will result in a 404 (as opposed to a 403 or directory listing, if enabled). Although a DirectoryIndex document will override this.
Additionally, the NC flag is superfluous and there is no need to backslash-escape the literal dot inside a character class.
You could instead check that the corresponding .php file exists before rewriting, instead of checking that the requested URL does not map to a file.
For example:
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]
The request is now only rewritten when the corresponding .php file exists, which naturally avoids any conflicts with directories.
Related
I have a file structure like this.
Folder
- .htaccess
- Subfolder
- Otherfolder
- file1.html
- file2.html
- filea.html
- fileb.html
I can have many folders at the place of 'otherfolder' and I don't want to add code for each subfolder of 'Subfolder'.
i want to remove all other subfolders names except folder.
I just want to get URL like - mywebsite.com/folder/file.html
Edit
currently I am using this code snippet in .htaccess
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^subfolder/([^.]+)\.html$ /folder/$1 [L,R]
RewriteCond %{REQUEST_URI} !/folder/subfolder/
RewriteCond %{REQUEST_URI} !\.(css|js|jpg|gif|png|jpeg)$
RewriteRule ^(.+)/?$ /folder/subfolder/$1.html [L]
I can have many folders at the place of 'otherfolder' and I don't want to add code for each subfolder of 'Subfolder'.
This isn't possible in .htaccess alone. The problem is not in removing the subfolder from the URL (although this should already have been done in the internal link), the problem is internally rewriting the request back to the appropriate subfolder. There is no built-in mechanism to "search" for arbitrary files in .htaccess.
If you have a limited number of known subfolders then you can do this, but you need to add a rule (in the root .htaccess file) for every subfolder. However, this is not particularly efficient since you need to manually test for the existence of that file in each subfolder. You also have a potential problem of name collision. Obviously, if you effectively "flatten" the filesystem the file file1.html can only exist once on the filesystem, amongst all subfolders. If there is more than one file1.html then the first match wins.
In principle, you would need to do something like the following to rewrite a request for /folder/<file>.html back to /folder/subfolder/otherfolderN/<file>.html.
# Test "subfolder/otherfolder1"
RewriteCond %{DOCUMENT_ROOT}/folder/subfolder/otherfolder1/$0 -f
RewriteRule ^[^/.]\.html$ subfolder/otherfolder1/$0 [L]
# Test "subfolder/otherfolder2"
RewriteCond %{DOCUMENT_ROOT}/folder/subfolder/otherfolder2/$0 -f
RewriteRule ^[^/.]\.html$ subfolder/otherfolder2/$0 [L]
# Test "subfolder/otherfolder3"
RewriteCond %{DOCUMENT_ROOT}/folder/subfolder/otherfolder3/$0 -f
RewriteRule ^[^/.]\.html$ subfolder/otherfolder3/$0 [L]
The parent /folder/ could be abstracted out of the RewriteCond TestString if you wish, but the subfolder and otherfolderN would need to be hardcoded. (Although subfolder could be manually assigned to an environment variable to save repetition.)
Aside:
RewriteCond %{REQUEST_URI} !/folder/subfolder/
RewriteCond %{REQUEST_URI} !\.(css|js|jpg|gif|png|jpeg)$
RewriteRule ^(.+)/?$ /folder/subfolder/$1.html [L]
A "problem" with this code is that it rewrites the request regardless of whether the target file exists or not. This is OK if you are rewriting all requests to a single subfolder, but if you have multiple subfolders then you must check for the target file's existence before rewriting.
This also rewrites the request even if it already maps to an existing file. So any legitimate files in the /folder/ directory (eg. filea.html and fileb.html in your file structure) would not be accessible.
This also rewrites every file type (except for the few file extensions listed in the preceding condition). It would, for instance rewrite a request for foo/bar/file.webp to /folder/subfolder/foo/bar/file.webp.html. If you are only wanting to rewrite .html files then include this in the RewriteRule pattern and the preceding condition is not required.
I tried many commands like the following
RewriteRule ^(.*?)/(.*?)/(.*?)$ $1.php?$2=$3 [L]
in .htaccess to hide the php extension from the URL but do not work, I have the following site.org/home.php and I want it to site.org/home, how can I do this? Is it possible to do it without modifying .htaccess file as well?
I tried this as well in the .htaccess file and doesn't work
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(.*)$ $1.php
</IfModule>
You don't actually "hide" the extension using .htaccess (if that is what you are expecting). You must first remove the .php extension in your HTML source, in your internal links (Apache/.htaccess should not be used to do this). The extension is now "hidden" (but the links don't work).
You then use .htaccess to internally rewrite the extensionless URL back to the .php extension in order to make the URL "work".
For example:
RewriteEngine On
# Rewrite to append ".php" extension if the file exists
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.+) $1.php [L]
Given a request for /home, the above will internally rewrite the request to /home.php if home.php exists as a physical file in the document root.
Note that this rule does assume your URLs do not end in a slash. eg. It expects /home and not /home/. if you request /home/ then it will result in a 404, since /home/.php does not exist.
The preceding condition first checks that the requested URL + .php exists as a physical file before rewriting the request. This is necessary in order to prevent a rewrite loop (500 error).
If your URLs do not contain dots (that are otherwise used to delimit the file extension) then the above can be optimised by excluding dots in the matched URL-path. ie. Change the RewriteRule pattern from (.+) to ^([^.]+)$. This avoids your static resources (.css, .js, .jpg, etc.) being unnecessarily checked for the corresponding .php file.
If you are changing an existing URL structure that previously used the .php extension and these URLs have been indexed by search engines and/or linked to by third parties then you should also redirect requests that include .php in order to preserve SEO. This redirect should go before the above rewrite, immediately after the RewriteEngine directive:
# Redirect to remove ".php" extension
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.+)\.php$ /$1 [R=301,L]
The preceding condition that checks against the REDIRCT_STATUS environment variable ensures that only direct requests are stripped of the .php extension and not rewritten requests by the later rewrite (which would otherwise result in a redirect loop).
NB: Test with a 302 (temporary) redirect first to avoid potential caching issues.
RewriteRule ^(.*?)/(.*?)/(.*?)$ $1.php?$2=$3 [L]
This does considerably more than simply "removing" (or rather "appending") the .php extension.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(.*)$ $1.php
</IfModule>
This will result in a rewrite-loop, ie. a 500 Internal Server Error response as it will repeatedly append the .php extension again and again to the same request.
(The <IfModule> wrapper is not required.)
Please could I have some help redirecting URLs to a subfolder so that everything in https://example.com is rewritten to https://example.co.uk/subfolder?
The .htaccess file needs to be in /subfolder.
You could do something like the following in the root .htaccess file to rewrite all direct requests to the subfolder.
RewriteEngine On
# Rewrite all direct requests to the `/subfolder` directory
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^ subfolder%{REQUEST_URI} [L]
The check against the REDIRECT_STATUS environment variable ensures that only direct requests from the client (as opposed to internally rewritten requests) are rewritten to the /subfolder directory (thus avoiding a rewrite loop).
This also means that a direct request for /subfolder itself will also be rewritten to the /subfolder directory (ie. /subfolder/subfolder) - so you can have a sub-subfolder of the same name if you wish (otherwise direct requests for /subfolder will result in a 404). That is, unless you have an additional .htaccess file in the subfolder that also contains mod_rewrite directives, in which case these directives will be overridden.
UPDATE: Following your question update that now states the following...
The .htaccess file needs to be in /subfolder.
In that case, this is not possible. The .htaccess file that rewrites requests to the /subfolder must be in the document root (the parent directory).
If the .htaccess file is in the /subfolder itself then it will simply never be processed for requests outside of that subfolder in order to rewrite the request.
MrWhite already gave nearly all the explanation I should have attached to my answer. So, like he already stated in his answer, the directives given below should be written into the .htaccess file that is located in the folder where https://site1.co.uk points to for it to work as you expect.
Here are the directives you can use.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /subfolder/$1 [QSA,L]
</IfModule>
The first RewriteCond will help make sure that the request is not for a file that already exists in the folder that the .htaccess file is located.
The second RewriteCond line is similar to the first but this checks for a folder instead. After this line, you can, and probably should, add the REDIRECT_STATUS line from MrWhite's answer. See his answer for the explanation.
The RewriteRule line uses Regular Expressions (RegEx) to effect the rewrite. Remember to replace subfolder on this line to name of the folder you wish to use and this folder should exist in the same location that the .htaccess file is located, and like already explained, this must be the folder that https://site1.co.uk points to.
Hope this helps.
After entering the code below, my home page gives a 403 error. The rest of the site works perfectly. All instances of .html were removed.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Any advice?
Thank you!
example.com leads ti the 403 error. If I write example.com/index it works fine.
Something else must have changed for this to result in a 403 error. The code you posted won't actually do anything when you request example.com/ - the same as if that code didn't exist at all. (UPDATE: However, this assumes your .htaccess file is located in the document - it appears this is not the case - see below.)
However, what will trigger a 403 in such cases is when "formatted directory listings" are disabled and the directory index document cannot be found (or has been disabled).
So, try setting the appropriate directory index at the top of your .htaccess file:
DirectoryIndex index.html
It is the DirectoryIndex that serves the appropriate file when requesting your "home page", not your directives in .htaccess.
UPDATE:
It [.htaccess] is located in my root directory. Would it be better to put it in the public_html folder?
Yes, the code you posted should go in the /public_html directory (ie. your document root). If these directives are in a .htaccess file above the document root then the RewriteRule pattern will match the URL-path public_html/ and rewrite the URL to public_html/.html which is possibly where your 403 error is coming from ("dot" files are usually hidden/protected OS files and you may also have a directive in your server config blocking access. However, this behaviour may also be dependent on other factors in the server config/OS). However, with that code in the document root then a request for example.com/ (your home page) won't be processed by these directives (which is good) - mod_dir should then serve the index.html file in this instance.
However, you don't want to process "directories" anyway (public_html is obviously a "directory", not a file). Which is what's happening above. eg. .html shouldn't be appended to public_html/ to begin with (or example.com/path/to/directory/ or any other directory). This can be avoided by adding an additional condition to your rule block to avoid directories (as well as files). For example:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.]+)$ $1.html [L]
Simply adding that additional RewriteCond directive might be enough and still allow you to keep your .htaccess file above the document root. (However, you may still need to move the .htaccess file as well, as described above.)
Also, the NC flag is not required here and literal dots don't need to be escaped when used inside a character class.
You could also extend this code to first check the existence of the file (with a .html extension) before rewriting, although this may be unnecessary in your case. For example:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^.]+)$ $1.html [L]
This requires an additional "file check" which may be an unnecessary overhead.
I know very little about .htaccess files and mod-rewrite rules. Looking at my statcounter information today, I noticed that a visitor to my site entered a url as follows:
http://mywebsite.com/index.php/contact-us
Since there is no such folder or file on the website and no broken links on the site, I'm assuming this was a penetration attempt. What was displayed to the visitor was the output of the index.php file, but without benefit of the associated CSS layout.
I need to create a rewrite rule that will either remove the information after index.php (or any .php file), or perhaps more appropriately, insert a question mark (after the .php filename), so that any following garbage will be treated like a parameter (and will be gracefully ignored if no parameters are required).
Thank you for any assistance.
If you're only expecting real directories and real files that do exist, then you can add this to an .htaccess file. What it does is it takes a non-existent file or directory request and gives the user the index.php page with the original request as a query string. [QSA] appends any existing query string.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?$1 [PT,QSA]
I found a solution, using information provided by AbsoluteZero as well as other threads that popped up on the right side of the screen as the solution came closer.
Here's the code that worked for me...
Options -Multiviews -Indexes +FollowSymLinks
RewriteEngine On
RewriteBase /
DirectorySlash Off
# remove trailing slash
RewriteRule ^(.*)\/(\?.*)?$ $1$2 [R=301,L]
# translate PATH_INFO information into a parameter
RewriteRule ^(.*)\.php(\/)(.*) $1.php?$3 [R=301,L]
# rewrite /dir/file?query to /dir/file.php?query
RewriteRule ^([\w\/-]+)(\?.*)?$ $1.php$2 [L,T=application/x-httpd-php]
I got the removal of trailing slash from another post on StackOverflow. However, even after removing the trailing slash, the rewrite rule did not account for someone appending what looks to be valid information after the .php file
(For example: mysite.com/index.php/somethingelse)
My goal was to either remove the "/somethingelse", or render it harmless. The PATH_INFO rule locates a "/" after the .php file, and turns everything else from that point forward into a query string (which will usually be ignored by the PHP file).