如果文件存在于别处,如何重写规则

时间:2011-07-28 23:38:36

标签: php apache mod-rewrite

我一直在努力完成与许多框架相同的工作:让.php处理请求(即index.php),同时保留一个/application/public文件夹,其中包含应显示的所有元素如果他们存在。例如:

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

如果有example.com/images/a.jpg请求,则应显示/application/public/images/a.jpg,因为它存在。否则,index.php会将?uri=images/a.jpg作为查询字符串。

考虑到这一点,我写了以下.htaccess(放在/):

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]

但是,请求/application/public处存在的任何内容将请求重定向到index.php(例如,example.com/images/a.jpg最终为example.com/index.php?uri=images/a.jpg

Apache日志仅显示以下内容(请求example.com/javascript/index.php时):

  

文件不存在:/ home / jbayardo / www / test / javascript

你可以想象,这让我陷入了困境。

1 个答案:

答案 0 :(得分:3)

  1. 在第一个RewriteCond行的末尾添加[OR]

    目前逻辑是AND:目前它读作“如果它是一个存在的文件,如果它是一个存在的文件夹” ..这不是真的 - 条件不满意并且不会重写。

    您需要“如果它是存在的文件或存在的文件夹

    请参阅文档:http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritecond(您需要向下滚动一下)。

  2. 即使规则#1正常工作,它仍然会被重写为index.php?uri=$1 - 因为那是你告诉Apache要做的事情。您需要添加一个条件以防止重写已重写的URL(请记住,当Apache重写URL时,它会进入下一次迭代并从顶部开始再次匹配所有规则 - 这就是它的工作原理。)

    < / LI>
  3. 不需要RewriteRule模式中的?

  4. 这就是我的看法:

    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]