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

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.

Related

htaccess RewriteRule with a variable not working

This rule takes us to the error page
RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]
I have the following in my .htaccess file
<IfModule mod_rewrite.c>
RewriteRule ^sucuri-(.*)\.php$ - [L]
</IfModule>
# END - Allow Sucuri Services
<Files 403.shtml>
order allow,deny
allow from all
</Files>
ErrorDocument 404 /404.php
Options +FollowSymLinks
Options +MultiViews
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
RewriteCond %{HTTP_HOST} !^www.xxxxx.com$ [NC]
RewriteRule ^(.*)$ https://www.xxxxx.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ci_index.php?/$1 [L]
## Remove php extension
RewriteCond %{REQUEST_URI} !^/index.php$
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]```
With the following rule
```RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]```
Trying to achieve the following -
```https://www.xxxxx.com/latest?auth=US-mobile-county
to
https://www.xxxxx.com/latest/US-mobile-county```
This rule takes us to the error page RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]
You've not stated precisely what "error page" you are referring to? Or what is expected to handle this request. This directive is not correct by itself, so it's not immediately clear what it is you are trying to do. I'm assuming the intention is to rewrite to latest.php (not latest as suggested by this rule, and mentioned later in the question) - since this would seem to be the only reason to implement such a rule (and your question is tagged php). By rewriting to latest only you are dependent on other directives appending the .php extension - and therein lies a conflict.
There are a number of issues with the directives as posted that is preventing this from working. Notably, the rules are in the wrong order and the use of MultiViews (probably in an attempt to get extensionless URLs working) is compounding matters. In fact, it doesn't look like the rule in question is actually being processed at all.
Without MultiViews, and due to the order of the directives, a request of the form /latest/something would be rewritten to /ci_index.php?/latest/something (presumably a CodeIgniter front-controller) which I would guess would result in a CI generated 404 response. However, since MultiViews has been enabled mod_negotiation first "rewrites" the request to /latest.php/something, which doesn't match any of your rules so either results in a 404 (depending on your server config) or calls latest.php but without any URL parameter, which presumably causes your script to fail?
https://www.xxxxx.com/latest/US-mobile-county
Also, note that your example URL contains hyphens (-), but the regex in your directive (ie. ^latest/([A-Za-z0-9]+)$) does not permit hyphens so it wouldn't have matched anyway.
Try the following instead, replacing everything after the ErrorDocument directive:
# Disable MultiViews
Options +FollowSymLinks -MultiViews
RewriteEngine on
# Redirect HTTP to HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Redirect non-www to www
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]
# Rewrite "/latest/something" to "/latest.php?auth=something"
RewriteRule ^latest/([A-Za-z0-9-]+)$ latest.php?auth=$1 [L]
# Allow extensionless PHP URLs to work
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]
# Front-controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ci_index.php?/$1 [L]
Note that I've reversed the order of the directives so that the rule in question is now first and the CI front-controller is now last. The order of the directives in .htaccess is important.
Since you had enabled MultiViews (now disabled in the above), your rule to enable PHP extensionless URLs (that you had labelled "Remove php extension") was not actually being used at all (unless you had directories or files that contained dots, other than that used to delimit the file extension).

.htaccess 301 redirect with exclusion does not work

I try to use a simple 301 redirect
from domain1.com/folder/ to domain2.com/
but excluding domain1.com/folder/subfolder
I use the following code in .htaccess:
RedirectMatch 301 ^/folder/((?!subfolder).*)$ https://domain2.com/$1
but it simply redirects all the requests, including the requests to subfolder.
Please, help to fix the line to make it work as described. Thank you!
here is the complete code of .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /folder/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /folder/index.php [L]
</IfModule>
RedirectMatch 301 ^/folder/((?!subfolder).*)$ https://domain2.com/$1
Try it like this using mod_rewrite instead:
(NB: This assumes the .htaccess file is located in the document root.)
# /.htaccess
# Redirect all direct requests, except "subfolder"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond $1 !^subfolder($|/)
RewriteRule ^folder/(.*) https://domain2.com/$1 [R=301,L]
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /folder/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /folder/index.php [L]
</IfModule>
It is important that the redirect goes before the rewrite to your front-controller.
You will need to ensure your browser cache is cleared before testing and test with a 302 (temporary) redirect to avoid potential caching issues.
UPDATE:
Yes, /folder has it's own .htaccess (this is the file I am working at all this time). Yes, /folder is where Wordpress is installed.
In that case you would need to change the above redirect to read as follows (it won't do anything otherwise):
# /folder/.htaccess
# Redirect all direct requests, except "subfolder"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond $1 !^subfolder($|/)
RewriteRule (.*) https://domain2.com/$1 [R=301,L]
Basically, you need to remove folder/ from the start of the regex that matches the URL-path. The URL-path that the RewriteRule pattern matches against is relative to the directory that contains the .htaccess file.
The addition of the check against the REDIRECT_STATUS env var is to ensure that rewritten requests to the WP front-controller (when subfolder is requested) are not redirected.
You can also "simplify" the WordPress directives that follow (although if these are enclosed in # BEGIN WordPress / # END WordPress comment markers then you should leave the directives as they are since they are maintained by WordPress). For example:
RewriteEngine On
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
The RewriteBase directive is not required. And neither is the <IfModule> wrapper. (But as I said above, only change this if you are hand-coding the .htaccess and not letting WordPress maintain it.)

How can I rewrite rules for subfolders?

I have a problem with a simple rewrite rule in htaccess ...
My htaccess like this :
RewriteEngine On
RewriteBase /
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteRule ^company$ /company.php?lang=en [QSA]
RewriteRule ^company/about$ /article.php?lang=en [QSA]
In local, it works.
But online it doesn't work.
If I go to the URL "www....com/company/about", I have the company.php page ...
Can you explain to me what's my problem ?
Thanks a lot
Have it this way:
Options -MultiViews
RewriteEngine On
RewriteBase /
## Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)/+$
RewriteRule ^ %1 [R=301,NE,L]
RewriteRule ^company$ company.php?lang=en [L,NC,QSA]
RewriteRule ^company/about$ article.php?lang=en [L,QSA,NC]
Important change is disabling option MultiViews. Option MultiViews (see http://httpd.apache.org/docs/2.4/content-negotiation.html) is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So if /file is the URL then Apache will serve /file.php (if that exists in your system).
I have also added L (last) and NC (ignore case) flags in your 2 rules.

.htaccess URL rewrite not working, tried all possible options

I was trying to rewrite a URL for making my site SEO friendly, but .htaccess rewrite not seems to work.
My URL is
www.tasteofkochi.com/dine-detail.php?a=150
I need this to look like
www.tasteofkochi.com/sometext/150
I did the simple formula but it's not reflecting, intact nothing happens at all. If I add some junk char in htaccess, site crashes, which means htaccess is working fine. Also I added a formula to remove .php extn, and that too works fine. Only issue is with this one. Can anyone please help me. I enable rewrite in httpd and allow all in directories, still not working.
Below is my .htacces
RewriteEngine on
Options +FollowSymLinks -MultiViews
RewriteBase /
## hide .php extension
# To externally redirect
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L,NC]
## To internally redirect
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [L]
RewriteRule ^detail/([0-9]+)/?$ dine-detail.php?a=$1 [NC,L]
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*) index.php?p=$1 [L,QSA]
We can create pretty urls with .htaccess and php by mainly two files one is .htaccess and another index.php
Example

Symfony2: simple rewrite rule in vhost to strip .html extention out

Since I migrated my project on Symfony2, I also avoided to use .html extensions previously used for my generated urls.
So, after looking at some examples, I'am trying to execute this in my /etc/apache2/sites-available/mysite:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)\.html$ $1 [NC,L]
#this is the standard rewrite rule to redirect every request to /web/app.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]
</IfModule>
I have tried many combinations but no one seems to work. Any Help? Thanks