I'm working on a project that has some mod_rewrite rules. These seem inefficient because of the L and END flags for each rule. Each rewrite tends to make one small adjustment to some old, outdated urls, but then pulls the trigger on a 301 redirect immediately. I've been trying to figure out how to do numerous RewriteCond and RewriteRule blocks but then ultimately only redirect if any single one of them yielded a change. Following the rules that do a 301 redirect for old urls are a couple of other rules that will a) route all requests to my index.php file (useful for SEO-friendly urls) and b) route subdomain requests to a particular controller.

The rewrite rules, which are in an apache conf, not an .htaccess file look something like this:

# 1- remove deprecated html suffix
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^(.*).html$ $1 [L,R=301,END]

# 2 - remove trailing slashes except for directories
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [L,R=301,END]

# 3 - route naked domain request to www, i.e., "example.com" => "www.example.com"
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com%{REQUEST_URI} [R=301,QSA,END]

# 4 - Checks to see if the user is attempting to access a valid file,
# such as an image or css document, if this isn't true it sends the
# request to the front controller, index.php
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php$1 [L,NC,QSA]

# 5 - route non-www subdomain request foo to https://www.example.com/subdomain/foo
# actual rule TBD...I'd like to request assets from www domain and only have this work for
# requests without a pathname (i.e., foo.example.com and foo.example.com/ but not
# foo.example.com/path

Is there any way to have a mod rewrite rule that detects whether prior rewrites have yielded any change from the original request? I imagine I could get rid of the L and END flags and put such a rule between #3 and #4. If not, does anyone have suggestions for efficiently combining these multiple rewrites (which might cause multiple requests and multiple rewrites) into a single, efficient rewrite?

NOTE: I posted this question on stack exchange but so far no responses.

    Not my area of expertise (if I even have one?), but wondering if you can merge several/all of those rules together via "one regex to rule them all" by using multiple parenthesized sub-patterns, then using their positional "variables" ($1, $2, etc...) in the rewrite rule?

    NogDog

    Thanks for your response.

    Sadly, I think the RewriteCond of the various rules presents a conflict. For the trailing slash and .html removal, it is the !-d condition against the request filename, but for the www enforcement, the RewriteCond checks the HTTPHOST and would need to apply even if the request is a directory.

      Write a Reply...