0

Let me preface by saying that I'm fairly new to .htaccess authoring and have usually left the nitty gritty up to my hosting provider. I've recently decided to implement a hand rolled MVC framework in php and was using the .htaccess file to redirect using "seo" friendly urls. My MVC implementation uses the variables module, class, event, and parameter. They are specified in the url in that order, e.g. http://mydomain.com/module/class/event/parameter. I want it to work if you chop off any part of the url. This was all working fine until I moved my site up one level and subsequently copied my .htaccess file. Now I'm getting an infinite redirect loop with one of the rules that was working fine before I moved it.

Here is my .htaccess file:

Options +FollowSymLinks 
RewriteEngine On 

RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^$ /index.php?module=default&class=home [QSA,L]

RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)$ /index.php?module=$1 [QSA,L]

RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ \
    /index.php?module=$1&class=$2&event=$3 [QSA,L]

RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ \
    /index.php?module=$1&class=$2&event=$3&parameter=$4 [QSA,L]

Now, if I take out the section that reads:

RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)$ /index.php?module=$1 [QSA,L]

It works great. The problem is if I leave that out and someone types http://mydomain.com/module I get a 404 (since that directory doesn't exist and none of the rules are matching). So why does that rule now not work and why did it work when index.php (and this .htaccess file) are in a sub-directory?

5
  • are these rules repeated in child directory below this one? Also you might want to just use a php based router. This way you have a simpler set of rules jsut going to index.php and then you let php sort out what the variabel positions are based on a spec you supply. You could right your own or you could use the Zend Framework components (though you might need to switch to their front controller or at least adapt yours to their interface). Commented Jun 23, 2011 at 16:31
  • Hello, have you considered asking in serverfault.com ? Commented Jun 23, 2011 at 16:31
  • @prodigitalson No the rules are not repeated in a child directory. I had a child directory, called public, that my framework sat in previously. My top level directory had a rule that just redirected to the public directory if no directory was specified on the url. Like I said, all this worked just fine before I moved the site up a level. I'm going to take a look at the php router solution. Commented Jun 23, 2011 at 16:51
  • @Herr Kaleun Good idea, I'll post over there as well. Thanks! Commented Jun 23, 2011 at 16:52
  • your welcome ;) they will take care of your problem. Commented Jun 23, 2011 at 16:53

1 Answer 1

2

Well it looks like the php router solution is the best. Thanks to @prodigitalson for the heads up.

Here is the simplified .htaccess I am now using

RewriteEngine On

# Disable rewriting for existing files or directories
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# redirect all other requests to index.php
RewriteRule ^.*$ index.php [PT,L]

RewriteRule ^$ index.php [PT,L]

And this "magic" line of code does all the heavy lifting that the .htaccess was doing before:

$url = explode('/', trim($_SERVER['REQUEST_URI'], '/'));

Now I can assign my module, class, event, and parameter values from the $url array. It also solves a problem I had where I may need more than one parameter to an event. I didn't want to have to keep adding rules to the .htaccess file for each level. Now I can supply an arbitrary number of parameters and deal with the routing logic in code.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.