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]