Apache2 mod_rewrite directive The website I'm working on is essentially project-management software. Each project has a code (alphanumeric lowercase, with hyphens). The URL must include the codes and treat them as directories.

website.com/p/&lt;code&gt;/&lt;page&gt; =&gt; website.com/p/&lt;page&gt;?code=&lt;code&gt;


Each project will have files associated with it. All file downloads are handled through a single script called 'files.php'. The file name itself must be in the URL. Files.php can also index all the files, only when $_GET['file'] is empty.

website.com/p/&lt;code&gt;/files/&lt;filename&gt; =&gt; files.php?code=&lt;code&gt;&amp;file=&lt;filename&gt;


Another requirement is that all project codes must be treated as directories. And the files must also serve as a directory. Attempting to otherwise will cause redirection.

website.com/p/&lt;code&gt; (redirects to) website.com/p/&lt;code&gt;/
website.com/p/&lt;code&gt;/files (redirects to) website.com/&lt;code&gt;/files/


Below is my solution, however it feels sloppy. Any advice?

&lt;Directory ${DOC_ROOT}&gt;
        RewriteEngine On
        RewriteBase /
        RewriteCond  %{QUERY_STRING}  !code
        RewriteRule ^p/([a-z0-9\-]+)/files$ p/$1/files/ [R,L]
        RewriteCond  %{QUERY_STRING}  !code
        RewriteRule ^p/([a-z0-9\-]+)/files/(.*)?$ p/files.php?code=$1&amp;name=$2&amp;%{QUERY_STRING} [L]

        RewriteCond  %{QUERY_STRING}  !code
        RewriteRule ^p/([a-z0-9\-]+)$ p/$1/ [R,L]
        RewriteCond  %{QUERY_STRING}  !code
        RewriteRule ^p/([a-z0-9\-]+)/(.*)$ p/$2?code=$1&amp;%{QUERY_STRING} [L]
&lt;/Directory&gt;
It's an Apache config file. It isn't going to look pretty. :)

That being said, I don't understand why you have RewriteCond specified for any of these rules. What is that condition preventing? The rewritten URL's are not causing redirect, so it is not clear to me when you would ever run into the condition of having "code" as a query string parameter. 

These conditions really don't make sense for case when you are adding trailing slashes, and if you truly are getting query strings in these trailing slash use cases, you are effectively stripping the query string out of the redirect as you are not using QSA flag.

You should consider using R=301 flag instead of just R for these trailing slash redirect use cases in order to signal to the client that this is permanent location for the resource that is to be used.

I personally find it easier to read through rewrite logic and have that logic to be less error prone if all redirects are handled first in the file, followed by more complex rewrite logic.

Finally, if your app keeps growing in complexity to where you have more of these redirect rules being added, you might consider simply moving to more of a front controller model where you evaluate the URI in PHP and route within your application accordingly.