How to merge several HTAccess rewrites? - apache

I have the following .htaccess file for my website:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /$1.php [R=301,L,QSA]
This works, in that the url 'hello' works, as well as 'hello.php'.
What I want to do, however, is the following:
Remove .php from 'hello.php' and redirect to 'hello'.
Remove (and redirect) trailing slash (if any).
How can this be done? I imagine it is quite simple.
EDIT: I was just working on this and it also has a redirect loop if you browse to 'hello.p' and if you browse to 'hello/'.

Your current rule is instructing Apache to 301 redirect to the route with the .php extension.
To prevent this, you'll need to remove the R=301 from the flag list.

Related

I need help placing a 301 redirect in my htaccess file of my new php site

I have a php website and my current .htaccess file is as follows:
<IfModule mod_rewrite.c>
#Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?page=$1 [NC,L,QSA]
Options -Indexes
</IfModule>
Now I want to do a 301 redirect on a URL. From example.com/folder/old-url-london.htm to example.com/new-url-london/
The problem is everytime I try something I get:
www.example.com/new-url-london/?page=folder/old-url-london.htm
Now I can't change this line (RewriteRule ^(.*)$ /index.php?page=$1 [NC,L,QSA]) as it is essential to the working of the website.
Any ideas?
I tried the following:
Redirect 301 /folder/old-url-london.htm example.com/new-url-london/
as well as
RewriteRule ^folder/old-url-london.htm$ /new-url-london/ [R=301,L]
Sounds like you are perhaps putting the rule in the wrong place. Or used the Redirect directive. And/or are perhaps now seeing a cached response.
You need to use mod_rewrite RewriteRule to avoid conflicts with the existing rewrite AND the rule needs to be at the top of the file, before the existing rewrite and ideally after the RewriteEngine directive.
For example:
Options +FollowSymlinks -Indexes
RewriteEngine On
RewriteRule ^folder/old-url-london\.htm$ /new-url-london/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?page=$1 [QSA,L]
You will need to clear your browser cache before testing, since any erroneous 301 (permanent) redirects will have been cached by the browser. Test first with 302 (temporary) redirects for this reason.
Don't forget to backslash-escape literal dots in the regex.
I tidied up a few other bits:
<IfModule> wrapper is not required.
Combined Options at the top and re-enabled FollowSymLinks (since it is required by mod_rewrite)
RewriteBase is not required in the directives you've posted.
Removed spurious spacing.
NC flag not required on the rewrite since the pattern .* already matches everything.
The anchors on the pattern ^(.*)$ are not required since regex is greedy by default.

htaccess redirect subfolder to root

This has been frustrating me and I can't find the same issue, maybe I am just searching wrong. Someone messed up and we have a bunch of Google links to a subfolder that does not exist. So I am trying to do a 301 redirect in htaccess to sort that out.
The problem is I can't seem to get the redirect to work more than one folder deep.
Example. http://example.com/subfolder/someOtherFolder redirects to http://example.com/someOtherFolder just fine.
However http://example.com/subfolder/someOtherFolder/yetAnother stays on the same page and returns a 404.
This is the last variation of my entire .htaccess that returns the above results, nothing I've tried has returned anything but the above.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteRule ^sitefiles/(.*)/$ /$1 [R=301]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php
</IfModule>
Help? (I hate .htaccess >.<)
The problem is with this rule:
RewriteRule ^sitefiles/(.*)/$ /$1 [R=301]
This rule required a trailing slash on the requested URI
Instead:
RewriteRule ^sitefiles/(.*) /$1 [R=301]
Note that there's also a Redirect directive to do simple Redirects. In your case:
Redirect /sitefiles /
Finally, note that the entirety of that Rewrite block can be replaced with:
FallbackResource /index.php
Thus, the final recommended (best practice) configuration would be:
Redirect /sitefiles /
FallbackResource /index.php
Rather than using Rewrite at all.

Simple .htaccess rewrite rule but doesn't work properly

I've trying to rewrite one url but something doesn't work as must and I get the massage
Not Found
The requested URL /1/1.html was not found on this server.
This is what I have in .htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^/([^/]*)/([^/]*)\.html$ /view.php?id=$1&name=$2 [L]
And this is the href link for this case
href="/'.$row['id'].'/'.$row['name'].'.html"
Any idea why is this?
You must remove leading slash in your rule
RewriteRule ^([^/]+)/([^/]+)\.html$ /view.php?id=$1&name=$2 [L]
You need a leading slash in your rules only if you write it directly in httpd.conf instead of .htaccess files.
You also need it until Apache 2.4 if i don't make a mistake

Apache2 mod_rewrite pattern restriction?

So I have a site that I want to make SEO friendly by using mod_rewrite. I want to make the URLs easy to remember by dropping the .php on the end of them and using mod_rewrite to re-attach them later on. So for example say http://example.com/about would point to http://example.com/about.php. I have the RewriteRule that should work from my experience but for some reason doesn't.
My rule:
RewriteEngine On
RewriteRule ^/?about$ about.php [L]
RewriteRule ^/?faq$ faq.php [L]
Now these rules don't work like that exactly. it seems that if I rename the files to blah.about.php and blah.faq.php and change the RewriteRule lines to reflect the new filenames it works.
Is this a restriction of mod_rewrite where the Pattern can't be so close to the target file?
Try this:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(.*)\.php [NC]
RewriteRule ^ /%1 [R=301,QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^([^/]+)/?$ $1.php [L]
First rule redirect the request to phpless page and the next internally to the php file itself.
Is this a restriction of mod_rewrite where the Pattern can't be so close to the target file?
Its not really a restriction, you just can't redirect the php file to non-php and then back to it as it generates a loop, so what we do is capture the request and redirect from there and then internally redirect to the file.
Unless of course like you have seen they have a different naming.

.htaccess rewrite all 'other' URLs

Hopefully this is a simple one. I have a really basic .htaccess that rewrites any request to /admin (or /admin/etc) to /_admin/index.php. So far so good:
#Options All -Indexes
RewriteEngine On
RewriteBase /admin
RewriteRule ^admin/$ /_admin/index.php [QSA]
RewriteRule ^admin$ /_admin/index.php [QSA]
RewriteRule ^admin/(.+)$ /_admin/index.php [QSA]
What I also want is a generic "catch all else" rule that rewrites any other url (/users, /turnips/, /some/other/path and so forth) back to /index.php
I can't seem to get that to work - its either server error 500's or /admin also gets rewritten to the root page. I'm sure I just need to do something with RewriteCond but I can't figure it out.
Thanks!
Add this after the other rules. It would be the default rule if the previous rules are not applied.
RewriteBase /
RewriteCond %{REQUEST_URI} !index\.php [NC]
RewriteRule .* index.php [L,QSA]
First of all I suggest you add the L flag to your rewrites so you're sure to avoid unintended matches after matching a rewrite (unless intended of course).
Secondly WordPress uses the following code to rewrite all URLs that are not matching index.php OR a file that already exists. This way files accessed directly like images, text files, downloads etc are not rewritten. Note that originally it also included the line RewriteCond %{REQUEST_FILENAME} !-d to also not rewrite directories but you seem to want that behaviour:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /index.php - [L]
Please see if this fits your needs.