Home > OS >  htaccess/mod_write: Help to improve/correct rewrite rules
htaccess/mod_write: Help to improve/correct rewrite rules

Time:11-09

I would like to rewrite the following URLs (along some others; not all files are in the /app folder):

/app/12345/process/789 => /app/process.php?contract_id=12345&id=789
/app/12345/login =>       /app/login.php?contract_id=12345
/app/12345/settings =>    /app/settings.php?contract_id=12345
/app/12345/tags =>        /app/tags.php?contract_id=12345
/app/12345 =>             /app/start.php?contract_id=12345
/app/login =>             /app/login.php

With your great help on stackoverflow I got so far:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^app/([^/] )/process/([^/] )/?$         app/process.php?contract_id=$1&id=$2 [L,NC,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^app/([^/] )/(login|settings|tags)/?$       verfahrensverzeichnis/$2.php?contract_id=$1 [L,NC,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^app/([^/] )/?$                         app/start.php?contract_id=$1 [L,NC,QSA]

I need a rule for the last redirect:

/app/login =>             /app/login.php

CodePudding user response:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^app/([^/] )/process/([^/] )/?$         app/process.php?contract_id=$1&id=$2 [L,NC,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^app/([^/] )/(login|settings|tags)/?$       verfahrensverzeichnis/$2.php?contract_id=$1 [L,NC,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^app/([^/] )/?$                         app/start.php?contract_id=$1 [L,NC,QSA]

Some comments on your existing rules:

  • All the filesystem checks would seem to be superfluous. I can't imagine that any of these requests could possibly map to a physical file or directory? Could /app/12345 be a physical directory on the filesystem? Filesystem checks are relatively expensive so are best avoided if possible. At the very least it is contributing to unnecessary code bloat.

  • Is the "id" numeric only? Your example URLs use a numeric-only id (2nd and optional 4th path segment), but you are allowing for "anything" in your rule. You should be as specific as possible. And this would naturally avoid conflicts with the rule you are stuck on, ie. /app/login to /app/login.php.

  • Your example URLs do not have a trailing slash, however, you are allowing for an optional trailing slash in your rules. Is this necessary? This potentially creates a duplicate content issue, since you now have two different URLs (one with and one without a trailing slash) that map to the same resource. If there could be a trailing slash on these URLs then this should be resolved with a canonical redirect (for SEO), not an internal rewrite.

  • You've used the NC flag on all these rules. Is the incoming URL really expected to be different case? Again, this potentially causes a duplicate content issue since /app/12345/process/789 and /APP/12345/PROCESS/789 are two different URLs.

  • What's verfahrensverzeichnis in the 2nd rule?

I need a rule for the last redirect:

/app/login =>             /app/login.php

This is arguably the simplest of all your rewrites, however, currently your last rule would conflict with this request and end up rewriting the request to app/start.php?contract_id=login. So you would either need to put this rule first, or restrict your regex so you only match numeric IDs as I mentioned above (preferable), which would naturally avoid this conflict.

So, taking the above points into consideration, your rules become:

# Ensure that MultiViews is disabled (must be disabled for these rules to work)
Options -MultiViews

RewriteRule ^app/(\d )/process/(\d )$ app/process.php?contract_id=$1&id=$2 [QSA,L]

RewriteRule ^app/(\d )/(login|settings|tags)$ app/$2.php?contract_id=$1 [QSA,L]

RewriteRule ^app/(\d )$  app/start.php?contract_id=$1 [QSA,L]

RewriteRule ^app/login$ app/login.php [L]
  • Related