RedirectMatch and Redirect interfering with each other

RedirectMatch and Redirect interfering with each other

In the example you’ve given, RedirectMatch (mod_alias) and RewriteRule (mod_rewrite) are “interfering with each other”, not Redirect. Redirect is a mod_alias directive, that works with RedirectMatch – so you wouldn’t necessarily expect these to conflict in this way.

As mentioned above, RewriteRule is a mod_rewrite directive, whereas RedirectMatch (and Redirect) are mod_alias directives. Different Apache modules execute independently and at different times during the request, regardless of the apparent order in your .htaccess file. In the case of mod_alias and mod_rewrite, mod_rewrite always executes first.

So, in your example, the RewriteRule (2nd directive) will be processed before the RedirectMatch directive that precedes it – since they both match the URL /datingstories. Processing then continues through the file and the whole process starts over for a 2nd pass, when the first mod_alias RedirectMatch redirects the URL (RedirectMatch matches against the URL in the request, not the rewritten URL. So, this matches /datingstories again, not showprofile.php – the rewritten URL). This replaces the rewritten URL-path (showprofile.php) but keeps the query string (?username=dating). (However, it’s not clear from the directives you posted, why datingstories would get truncated to dating in the URL parameter – maybe there is a conflict with other directives.) The earlier rewrite is converted to an external redirect after the 301 HTTP status is applied.

The lesson here is that you should never mix redirects / rewrites from both modules – in order to avoid confusing conflicts such as this. Since WordPress uses mod_rewrite for its front-controller, you would ideally use mod_rewrite throughout. So, you should convert any mod_alias RedirectMatch (and Redirect) directives to use mod_rewrite RewriteRule instead.

For example:

RewriteRule ^datingstories /blog/category/relationships/datingstories/ [R=301,L]
RewriteRule ^([a-zA-Z0-9_-]+)$ showprofile.php?username=$1 [L]

And don’t neglect the L flag – to stop further processing (current pass through the file) when required.