Htaccess переписать цикл? - PullRequest
1 голос
/ 14 июля 2011

У меня есть загруженные пользователем файлы, которые хранятся в

/public/upload/*

например:

/public/upload/gallery/segway/child-on-a-segway.jpg

Мои текущие правила .htaccess уже исключают часть /public, но мне все еще нужно избавиться от части /upload, НО, только для файлов с заданным расширением и не содержащихся в других каталогах, таких как js или img. Мой текущий .htaccess выглядит так (типично для проектов Zend Framework):

RewriteEngine On

RewriteRule ^\.htaccess$ - [F]

RewriteCond %{REQUEST_URI} =""
RewriteRule ^.*$ /public/index.php [NC,L]

RewriteCond %{REQUEST_URI} !^/public/.*$
RewriteRule ^(.*)$ /public/$1

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]

RewriteRule ^public/.*$ /public/index.php [NC,L]

В надежде избавиться от работающей части /upload, я написал это в конце моего .htaccess:

RewriteCond %{REQUEST_URI} ^(?<!upload|img|js|less|css)/.*(jpg|mp3|png)$
RewriteRule ^(.*)$ /upload/$1

Как правило, если файл имеет расширение jpg, png или mp3 и путь к нему НЕ начинается с «upload», «js», «css», «img» или «less», добавьте «upload» к URI запроса. Ну, это не удается. Когда я набираю в адресной строке: http://example.com/gallery/1/php193A.jpg, я получаю 303 ошибку:

У вас нет прав доступа к / загрузить // публичный / загрузить / публичный / загрузить / публичный / загрузить / публичный / загрузить / публичный / загрузить / публичный / загрузить / публичный / загрузить / публичный / загрузить / публичный / галерея /1/php193A.jpg/1/php193A.jpg/gallery/1/php193A.jpg/1/php193A.jpg/upload/public/gallery/1/php193A.jpg/1/php193A.jpg/gallery/1/php193A .jpg / 1 / php193A.jpg / загрузки / государственные / загрузки / государственные / галерея / 1 / php193A.jpg / 1 / php193A.jpg / галерея / 1 / php193A.jpg / 1 / php193A.jpg / загрузки / государственные / галерея /1/php193A.jpg/1/php193A.jpg/gallery/1/php193A.jpg/1/php193A.jpg...

И URL продолжается и продолжается несколько десятков строк, как если бы он был зациклен.

Это первый раз, когда я имею дело с правилами переписывания .htaccess. Я был бы признателен за помощь в их установлении, так как я полностью потерян здесь. Заранее спасибо.

1 Ответ

1 голос
/ 14 июля 2011

Вы сказали, что "написали это в конце моего .htaccess" .TBH Я не вижу способа, как это правило должно быть достигнуто ( порядок правил имеет значение ) без изменения некоторых других правил (например, удаление флага L).

Давайте рассмотрим этот запрос: /gallery/segway/child-on-a-segway.jpg.

  1. Это будет переписано в /public/gallery/segway/child-on-a-segway.jpg по этому правилу: RewriteRule ^(.*)$ /public/$1

  2. Поскольку такого файла нет, он будет переписан в /public/index.php по этому правилу: RewriteRule ^public/.*$ /public/index.php [NC,L].Из-за [L] перезапись флага переходит к следующей итерации.

  3. На 2-й итерации перезаписи это правило RewriteRule ^.*$ - [NC,L] видит, что /public/index.php существует, и прекращает любые дальнейшие перезаписи.


Учитывая все вышеизложенное, становится очевидным, что такое дополнительное правило необходимо поместить где-то посередине, не изменяя ни одно из существующих правил.Это правило, которое я придумаю, соответствует вашим требованиям (на основе вашей попытки переписать):

RewriteCond %{REQUEST_URI} !^/(public|img|js|css)/.*$
RewriteCond %{DOCUMENT_ROOT}/public/upload%{REQUEST_URI} -f
RewriteRule ^(.+\.(jpg|png|mp3))$ /public/upload%{REQUEST_URI} [NC,L]

Правильное место для его размещения, по моему мнению, было бы до этого правила: RewriteRule ^(.*)$ /public/$1,Такой .htaccess будет иметь следующее содержимое:

RewriteEngine On

RewriteRule ^\.htaccess$ - [F]

RewriteCond %{REQUEST_URI} =""
RewriteRule ^.*$ /public/index.php [NC,L]

RewriteCond %{REQUEST_URI} !^/(public|img|js|css)/.*$
RewriteCond %{DOCUMENT_ROOT}/public/upload%{REQUEST_URI} -f
RewriteRule ^(.+\.(jpg|png|mp3))$ /public/upload%{REQUEST_URI} [NC,L]

RewriteCond %{REQUEST_URI} !^/public/.*$
RewriteRule ^(.*)$ /public/$1

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]

RewriteRule ^public/.*$ /public/index.php [NC,L]

Я проверил - все работает.Это может быть не самым оптимальным, так как поиск файла выполняется (-f), но, учитывая, что он будет работать только для ограниченного числа расширений (это хорошее требование), все должно быть хорошо (если это будет для КАЖДОГО расширения, тоэто замедлит работу системы на занятом сервере / под нагрузкой).

PS Как я понимаю, шаблон (?< означает «просмотр переменной длины» (хотя я не на 100%уверен в этом).

...