开发者

How to RewriteRule if file exists elsewhere

I have been trying to accomplish the same as many frameworks do: having the request processed by a .php (namely, index.php), while keeping a /application/public folder which contains all the elements that should be shown in case they exist. For example:

folder /application/public
total 28K
92897619 drwxr-xr-x 5 1001 1001 4.0K Jul 29 00:07 .
92897616 drwxr-xr-x 7 1001 1001 4.0K Jul 28 23:31 ..
92897754 -rw-r--r-- 1 1001 1001   15 Jul 29 00:07 .htaccess
92897733 drwxr-xr-x 2 1001 1001 4.0K Jul 28 23:31 images
92897620 -rw-r--r-- 1 1001 1001  696 Jul 28 23:58 index.php
92897625 drwxr-xr-x 2 1001 1001 4.0K Jul 28 23:31 javascript
92897734 drwxr-xr-x 2 1001 1001 4.0K Jul 28 23:31 stylesheets

folder /:
total 24K
92831996 drwxr-xr-x 4 1001 1001 4.0K Jul 29 02:44 .
91980897 drwxr-xr-x 5    0    0 4.0K Jul  6 00:30 ..
92831975 -rw-r--r-- 1 1001 1001  360 Jul 29 02:44 .htaccess
92897616 drwxr-xr-x 7 1001 1001 4.0K Jul 28 23:31 application
92832733 -rw-r--r-- 1 1001 1001  696 Jul 29 00:02 index.php
92897739 drwxr-xr-x 6 1001 1001 4.0K Jul 28 23:31 system

If there is a request for example.com/images/a.jpg, /application/public/images/a.jpg should be shown, as it exists. Otherwise, index.php would get ?uri=images/a.jpg as query string.

With this in mind, I wrote the following .htaccess (placed at /):

Options +FollowSymLinks +Indexes
RewriteEngine on
RewriteBase /
RewriteCond %{DOCUMENT_ROOT}/application/public%{REQUEST_URI} -f
RewriteCond %{DOCUMENT_ROOT}/application/public%{REQUEST_URI} -d
RewriteRule ^(.*)?$ application/public/$1 [L]
RewriteRule ^(.+)?$ index.php?uri=$1 [PT,QSA,L]

Still, requesting for anything existent at /application/public redirects the request to index.php (for example, example.com/images/a.jpg ends up being example.com/index.php?uri=images/a.jpg).

开发者_如何学Python

Apache logs only show the following (when requesting example.com/javascript/index.php):

File does not exist: /home/jbayardo/www/test/javascript

This, as you can imagine, leaves me in the blank.


  1. Add [OR] at the end of first RewriteCond line.

    Currently the logic is AND: currently it reads as "if it is a file that exists AND if it is a folder that exists" .. which cannot be true -- conditions are not satisfied and rewrite does not occur.

    You need "if it is a file that exists OR if it is a folder that exists".

    See docs: http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritecond (you have to scroll down a bit).

  2. Even if rule #1 will work properly, it will still end up rewritten to index.php?uri=$1 -- because that what you are telling Apache to do. You need to add a condition to prevent rewriting already rewritten URLs (keep in mind, that when Apache rewrites URL, it goes to next iteration ans start matching all rules again from top -- that is how it works).

  3. The ? in RewriteRule patterns are not needed.

This is how I see it:

Options +FollowSymLinks +Indexes

RewriteEngine on
RewriteBase /

RewriteCond %{DOCUMENT_ROOT}/application/public%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/application/public%{REQUEST_URI} -d
RewriteRule ^(.+)$ application/public/$1 [L]

RewriteCond %{REQUEST_URI} !^/(application/public/|index.php)
RewriteRule ^(.*)$ index.php?uri=$1 [PT,QSA,L]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜