1

I need to create the following rule to place in my .htaccess

  1. Firstly I want to execetue file in the main folder (/) (if requestedfile exists)
  2. Secondly I'd like to search for this file in subfolder -> /subfolder
  3. And If the file doesn't exist in point 1 and 2 id like to redirect the request do /index.php

What would be the best way to do it.

Thanks for help :)

ps The first point could be eliminated as a simpler solution. So if the user entered url /file.jpeg the server would serach for this file in /subfolder and if didn't find this file than it would redirect the rquest do index.php

Sebastian Dusza
  • 2,470
  • 2
  • 30
  • 54
  • Followup question -> http://stackoverflow.com/questions/9330058/mod-rewrite-redirect-request-to-subdir-with-many-subfolders-of-different-struct – Sebastian Dusza Feb 17 '12 at 14:34

2 Answers2

1

I am assuming your URL looks like this: somesite.com/subfolder/file.extension. If URL is different give details.
Add this to your .htaccess in your DocumentRoot.

Options +FollowSymLinks -MultiViews -Indexes

RewriteEngine on
RewriteBase /

RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]

RewriteCond %{REQUEST_URI} ^/([\w]+)/([\w]+\.[\w]+)$ [NC]
RewriteCond %{DOCUMENT_ROOT}/%2 -f 
RewriteRule ^ /%2 [NC,L] 

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]

RewriteRule ^ /index.php [L]

Changed to suit OPs requirement.

RewriteEngine on
RewriteBase /

RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]

RewriteCond %{REQUEST_URI} ([\w]+\.[\w]+)$ [NC]
RewriteCond %{DOCUMENT_ROOT}/%1 -f 
RewriteRule ^ /%1 [NC,L] 

RewriteCond %{REQUEST_URI} ([\w]+\.[\w]+)$ [NC]
RewriteCond %{DOCUMENT_ROOT}/subdir/%1 -f
RewriteRule ^ /subdir/%1 [L]

RewriteRule ^ /index.php [L]
ThinkingMonkey
  • 12,539
  • 13
  • 57
  • 81
  • But where do I define the name of the subfolder to search in -> /subfolder ? Lets say the user enters url http://domain/xxx.jpeg . I wan't first to look for the file in / then to look for the file in /subfolder and if the file is not found I want to redirect the request do /index.php – Sebastian Dusza Feb 17 '12 at 11:46
  • 1
    If you are on a shared hosting service, you might find that %{DOCUMENT_ROOT} doesn't work. If so do a `phpinfo()` script and look for variables such **PHP_DOCUMENT_ROOT** or **DOCUMENT_ROOT_REAL** which contain the same root directory. You can then use this instead, say `%{ENV:PHP_DOCUMENT_ROOT}`. – TerryE Feb 17 '12 at 11:49
  • 1
    Ooops, also %2 doesn't carry to next Rule so you need to use a different tack. – TerryE Feb 17 '12 at 11:54
  • 1
    @TerryE `RewriteCond backreferences: These are backreferences of the form %N (1 <= N <= 9), which provide access to the grouped parts (again, in parentheses) of the pattern, from the last matched RewriteCond in the current set of conditions.` Since, `RewriteCond %{DOCUMENT_ROOT}/%2 -f` does not have a regular expression string, It should carry over. – ThinkingMonkey Feb 17 '12 at 11:59
  • 1
    @ThinkinMmonkey, maybe they should but they don't. If you have `condA, condB, rule` then the %variables from condA are available in condB and the %variables from condB are available in rule. Since the logic is really `if(rule.regexp(...) && condA && condB) do replace`, the $ variables are available everywhere. – TerryE Feb 17 '12 at 12:08
  • @Seba check the updated answer & replace `subdir` with the actual name. – ThinkingMonkey Feb 17 '12 at 12:08
  • 1
    @TerryE special variants of CondPatterns do not have the option to specify a regular expression string. So, there is no matching that occurs to actually override the saved back-references of groups. Test out the rewriterules snippet I have written for affirmation. – ThinkingMonkey Feb 17 '12 at 12:14
  • 2
    Hummm, that's not what the documentation says, but if you say so ... I will check and look at the source. I would love to have a chat on this but I've got to do another job now. Maybe later :-) – TerryE Feb 17 '12 at 12:44
  • Guys, it seems that Your solution only works when there are no subfolders inside the subdir. I started another qustion. If you have time please take a look. Thank you very much :-) --> http://stackoverflow.com/questions/9330058/mod-rewrite-redirect-request-to-subdir-with-many-subfolders-of-different-struct – Sebastian Dusza Feb 17 '12 at 14:34
  • 1
    @seba yes, its designed that way. Looking at your other question. – ThinkingMonkey Feb 17 '12 at 15:28
  • Ok now i see that indeed Your solution works with subfolders but only *.jpg files can be downloaded from subfolders (for example subdir/Folder/xxx.jpg). Its strange but all other extensions redirect to index.php (tested *.jpeg, *.gif, *.js, *.css) – Sebastian Dusza Feb 17 '12 at 15:50
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/7854/discussion-between-seba-and-thinkingmonkey) – Sebastian Dusza Feb 17 '12 at 15:50
  • At the same time if file is stored directly under subdir it can be any other extension. ,,, domain.com/Folder/xxx.jpg - works ok ,,, domain.com/Folder/xxx.jpeg - doesn't work ,,, domain.com/Folder/test.js - doesn't work ,,, domain.com/test.js - works ok – Sebastian Dusza Feb 17 '12 at 15:57
1

This is just a supplemental to the approach ThinkingMonkey outlines. As I commented, the % variables are only available on the next cond or rule. However the rule $ variables are available for both the conds and the rule replacement string, hence rule 2 should be written as (with the same caveats about using DOCUMENT_ROOT):

RewriteCond %{DOCUMENT_ROOT}/$1 -f 
RewriteRule \w+/(\w+\.\w+)$ $1 [NC,L] 

or if you want to do the opposite

RewriteCond %{DOCUMENT_ROOT}/subdir/$1 -f 
RewriteRule (\w+\.\w+)$ subdir/$1 [NC,L] 
TerryE
  • 10,724
  • 5
  • 26
  • 48