Search code examples
.htaccessmod-rewritehttp-redirectsubdirectoryfile-exists

htaccess - redirect all requests within subdirectory, except if a requested file exists


I'm developing an app in php, and I need to set up a pretty broad .htaccess redirect. I did some reading and tried to write the RewriteConds myself, but it's a bit above my paygrade - I'm hoping someone with more experience can help. Here's what I'm trying to accomplish:

  • The app is contained in www.example.com/app/. Don't redirect anything above this directory.
  • Some files exist in this directory that will need to be accessed. Currently these are /app/includes/* and /app/sb_pages/*. This will change and expand in the future, so I need an elegant solution that encompasses all existing files. It's fine if the redirect triggers within these directories when a file isn't found - all I care about is being able to access the files within without the redirect triggering.
  • All other requests should be redirected to /app/index.php, with the trailing url passed in the querystring. For example, a request to /app/path1/path2/ should redirect to /app/index.php?path=path1/path2/
  • The redirect should not be transparent. When the user requests /app/path1/path2/, I want them to believe they have remained there. They should not see the url change to /app/index.php?path=path1/path2/.

Just for added clarity, here's a few cases to elaborate:

  • /app/includes/sidebar.php should not redirect.
  • /app/includes/nothing.html does not exist - redirect is OK
  • /app/path1/path2/ should redirect to /app/index.php?path=path1/path2/. User should still see their current URL as /app/path1/path2/.

I hope I've explained it clearly and pre-empted most questions. If you need clarification, please don't hesitate to ask. Thanks in advance for the help!


Solution

  • Try adding this to your .htaccess file in your document root:

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^app/(.*)$ /app/index.php?path=$1 [L,QSA]
    

    Note that if you want accesses to existing directories (as opposed to files) to also not be redirected, add a RewriteCond %{REQUEST_FILENAME} !-d above the rule.