RewriteRule ^post/article\.php$ {C:1}/{C:2}/{C:3}/{C:4}
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$ post/article.php?a=$1&b=$2&c=$3&id=$4
RewriteRule ^sitemap\.xml?$ sitemap.php
If used in .htaccess
these directives would result in a malformed internal rewrite - possibly a rewrite-loop (500 Internal Server Error response).
If used in a VirtualHost context they simply won't match so won't actually do anything.
In the <VirtualHost>
To write this in a VirtualHost context (not .htaccess
), you would need to do it like the following instead...
Note that if you have implemented an SSL cert and are using HTTPS only (ie. redirecting from HTTP to HTTPS in the <VirtualHost *:80>
container) then these directives need to go in the <VirtualHost *:443>
container. The <VirtualHost *:80>
can be relatively empty.
Your 2nd rule is close as you are really just missing some slash prefixes and flags.
In a server or virtualhost context, the URL-path matched by the RewriteRule
pattern is always the full root-relative URL-path, starting with a slash. And the substitution string (target URL) cannot be relative.
Options FollowSymLinks
RewriteEngine On
# Redirect direct requests for "/post/article.php?a=<a>&b=<b>&c=<c>&id=<id>"
# to the canonical URL: "/<a>/<b>/<c>/<id>"
RewriteCond %{THE_REQUEST} \?a=([^&]+)&b=([^&]+)&c=([^&]+)&id=([^&]+)\s
RewriteRule ^/post/article\.php$ /%1/%2/%3/%4 [QSD,NE,R=301,L]
# Rewrite "/<a>/<b>/<c>/<id>" to the underlying filesystem path
RewriteRule ^/([^/]+)/([^/]+)/([^/]+)/([^/]+)$ /post/article.php?a=$1&b=$2&c=$3&id=$4 [L]
# Rewrite "/sitemap.xml" to "/sitemap.php"
RewriteRule ^/(sitemap)\.xml$ /$1.php [L]
The NE
flag may be required on the first rule if you have any %-encoded values in the query string, in order to prevent these from being doubly encoded when redirecting to the corresponding URL-path.
The QSD
flag discards the query string from the initial request, otherwise, the query string is copied through to the target.
The %1
- %4
backreferences contain the values of the captured groups in the last matched CondPattern (RewriteCond
directive).
In .htaccess
To do this in .htaccess
you first need to enable .htaccess
overrides in the VirtualHost using the AllowOverride
directive - otherwise the .htaccess
file is going to be ignored. (And note the spelling, you've spelt it wrong 3 times in your question, in varying ways.)
For example:
<VirtualHost *:80>
ServerName example.in
ServerAlias www.example.in
DocumentRoot /path/to/document/root
<Directory /path/to/document/root>
Options FollowSymLinks
Require all granted
AllowOverride All
</Directory>
</VirtualHost>
Then, in .htaccess
you can write the directives as follows. They are very similar, except there is no slash prefix on the RewriteRule
pattern and the substitution string also does not need the slash prefix.
In a directory or .htaccess
context, the URL-path matched by the RewriteRule
pattern is less the directory-prefix so never starts with a slash. And the substitution string (target URL) can be a relative filesystem path.
For example, in .htaccess
:
RewriteEngine On
# Redirect direct requests for "/post/article.php?a=<a>&b=<b>&c=<c>&id=<id>"
# to the canonical URL: "/<a>/<b>/<c>/<id>"
RewriteCond %{THE_REQUEST} \?a=([^&]+)&b=([^&]+)&c=([^&]+)&id=([^&]+)\s
RewriteRule ^post/article\.php$ /%1/%2/%3/%4 [QSD,NE,R=301,L]
# Rewrite "/<a>/<b>/<c>/<id>" to the underlying filesystem path
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)$ post/article.php?a=$1&b=$2&c=$3&id=$4 [L]
# Rewrite "/sitemap.xml" to "/sitemap.php"
RewriteRule ^(sitemap)\.xml$ $1.php [L]
Test with 302 (temporary) redirects to avoid potential caching issues.
{C:1}/{C:2}/{C:3}/{C:4}
- That's an IIS thing. I assume here you are trying to canonicalise any direct request for/post/article.php?a=
etc.?^sitemap\.xml?$
- I assume the trailingl
should not be optional?