Как RewriteRule, если файл существует в другом месте - PullRequest
1 голос
/ 29 июля 2011

Я пытался выполнить то же, что и многие фреймворки: обрабатывать запрос с помощью .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 Ответ

3 голосов
/ 29 июля 2011
  1. Добавьте [OR] в конце первой строки RewriteCond.

    В настоящее время логика AND: в настоящее время она читается как ", если это файл, который существуетИ если это папка, которая существует " .., которая не может быть истинной - условия не выполняются и перезапись не происходит.

    Вам необходимо ", если это файл, который существует ИЛИесли это папка, которая существует ".

    См. документы: http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritecond (вам нужно немного прокрутить вниз).

  2. Дажеесли правило # 1 будет работать правильно, оно все равно будет переписано в index.php?uri=$1 - потому что это то, что вы говорите Apache.Вам нужно добавить условие, чтобы предотвратить перезапись уже переписанных URL-адресов (имейте в виду, что когда Apache переписывает URL-адрес, он переходит к следующей итерации и снова начинает сопоставлять все правила сверху - вот как это работает).

  3. Шаблоны ? в RewriteRule не нужны.

Вот как я это вижу:

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]
...