Viewed   549 times

I am writing a simple PHP-based MVC-ish framework. I want this framework to be able to be installed in any directory.

My PHP script grabs the request uri and breaks it off into segments. It makes segment 1 the controller and segment 2 the action. This goes all fine when I do this:

http://www.example.com/mvc/module/test/

It will go to the specific module controller and method. Now I have a default controller, the home controller, which is in folder home.

Now when I access this folder directly http://www.example.com/mvc/home/ It will display a 403 forbidden , because this folder does exist, instead it should also go back to http://www.example.com/mvc/index.php

If I would have installed the framework in a different folder, lets say folder framework it has to redirect back to http://www.example.com/framework/index.php

I would like to redirect every folder and php file back to the index.php, leaving everything else the way it is.

My first problem I encountered was it never redirects to the right folder, always to the domain root folder.

This is what I tried :

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

 Answers

4

Your rewrite rule looks almost ok.

First make sure that your .htaccess file is in your document root (the same place as index.php) or it'll only affect the sub-folder it's in (and any sub-folders within that - recursively).

Next make a slight change to your rule so it looks something like:

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

At the moment you're just matching on . which is one instance of any character, you need at least .* to match any number of instances of any character.

The $_GET['path'] variable will contain the fake directory structure, so /mvc/module/test for instance, which you can then use in index.php to determine the Controller and actions you want to perform.


If you want the whole shebang installed in a sub-directory, such as /mvc/ or /framework/ the least complicated way to do it is to change the rewrite rule slightly to take that into account.

RewriteRule ^(.*)$ /mvc/index.php?path=$1 [NC,L,QSA]

And ensure that your index.php is in that folder whilst the .htaccess file is in the document root.


Alternative to $_GET['path'] (updated Feb '18 and Jan '19)

It's not actually necessary (nor even common now) to set the path as a $_GET variable, many frameworks will rely on $_SERVER['REQUEST_URI'] to retrieve the same information - normally to determine which Controller to use - but the principle is exactly the same.

This does simplify the RewriteRule slightly as you don't need to create the path parameter (which means the OP's original RewriteRule will now work):

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]

However, the rule about installing in a sub-directory still applies, e.g.

RewriteRule ^.*$ /mvc/index.php [L,QSA]



The flags:

NC = No Case (not case sensitive, not really necessary since there are no characters in the pattern)

L = Last (it'll stop rewriting at after this Rewrite so make sure it's the last thing in your list of rewrites)

QSA = Query String Append, just in case you've got something like ?like=penguins on the end which you want to keep and pass to index.php.

Thursday, August 25, 2022
1

EDIT

I completely setup your files on my machine

//  /.htaccess

RewriteEngine on

RewriteRule ^(public)($|/) - [L,NC]

RewriteCond $1 !^(index.php|robots.txt)
RewriteRule ^(.*)$ index.php/$1 [L,QSA]

.htaccess in the public folder:

//  /public/.htaccess

Options -Indexes
RewriteEngine off

This disables rewriting like you wanted.

/public/                 -> 403 Forbidden
/public/favicon.ico      -> 200 File found
/public/not-existing.ext -> 404 File not found

Do you have a index.php in you public folder? Maybe you could remove that one..

What kind of machine your testing on?

I tested it on Linux + Apache 2 + PHP5.3

I can give you more support in the afternoon (my time +2 GMT)

EDIT 2

When I remove this line from /.htaccess is still works

RewriteRule ^(public)($|/) - [L,NC]

Everything is handled by the .htaccess in the public folder.

Maybe it's a caching problem in your browser. Try a different browser/clean up history/install app to remove cache.. (depending on what browser you're using)

Thursday, October 13, 2022
 
shardul
 
4

My best bet would be to simply add get variables to the regex, like so:

RewriteRule ^account/blogs/([0-9]+)/([^s?]+)/?(?(.*))?$ /account/blog.php?blogId=$1&$4 [L,QSA]

This would rewrite

/account/blogs/1/ThisIsWhereTheTitleGoes?delete=1

to

/account/blog.php?blogId=1&delete=1

It would also support additional variables.

Friday, November 18, 2022
 
dave_d
 
2

The following worked for me. NOTE: if your subdomain has its own .htaccess file (for example a WordPress site in your subdomain), you will have to edit that .htaccess file in addition to the main, domain .htaccess.

RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^((?!www.)[^.]+).domian.com$
RewriteRule ^https://%1.domain.com%{REQUEST_URI} [NE,L,R]

You can add other rewrite conditions above or below this, depending on when you want them executed. For example, Reghbendra Nayak's "Handle Front Controller..." code can be placed blow the https 'force' and it will execute.

Wednesday, October 26, 2022
 
3

Replace your current code by this one

Options -Indexes +FollowSymLinks
RewriteEngine On

# redirect "www" domain to https://example.com
RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

# redirect http to https (at this point, domain is without "www")
RewriteCond %{HTTPS} =off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
Sunday, October 9, 2022
 
mchv
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :