[ Background ]
This is the structure to my application:
app/
controllers/
...
modules/
...
views/
...
public/
css/
main.css
images/
...
js/
...
index.php
.htaccess
For various reasons (security, organization, etc.) the public application (website) is loaded and displayed by public/index.php
At the "root" of my server I have the following .htaccess
file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /BU/cs-602/developer-story/
RewriteRule ^(\/||index\.*)$ public/index.php [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RedirectMatch ^(/BU/cs-602/developer-story.)([\w\d\s\/\-\:\_%\ ]*\.css)$ $1public/$2 [L]
RewriteRule ^([\w\d\-\_\/\ ]*)$ public/index.php?p=$1 [L,QSA]
</IfModule>
These rules should rewrite/ redirect all requests from the server "root" to public/index.php
Since I am developing locally on my development server this project is not actually at the root of my server but is located at /BU/cs-602/developer-story/
This is why I added the RewriteBase
rule.
If I remove the RedirectMatch
rule everything from an MVC standpoint works:
URLs like http://localhost/BU/cs-602/developer-story
or http://localhost/BU/cs-602/developer-story/
become http://localhost/BU/cs-602/developer-story/public/index.php
AND URLs like http://localhost/BU/cs-602/developer-story/user/id
become http://localhost/BU/cs-602/developer-story/public/index.php?p=user/id
.
Here is a live htaccess test.
[ Question ]
How can I fix the .htaccess
file or the RedirectMatch
rule to redirect request to resources like CSS
or JS
files? The current rule works in the tester but not on my server unless I remove the RedirectMatch
rule.
I would like a URL like http://localhost/BU/cs-602/developer-story/css/main.css
to become http://localhost/BU/cs-602/developer-story/public/css/main.css
that way in my HTML I do something like:
<img src="images/logo.png">
The server actually loads:
<img src="public/images/logo.png">
This way I do not have to prefix all my resources with public/
.
[ Disclosure ]
This question is for help with a final project at my University, but this type question is allowed and not violating academic policies. Making a project with htaccess
and MVC
is not a requirement, just something I'm doing to challenge myself.
UPDATE:
Here is my original RedirectMacth
rule. Anything that is not a PHP or HTML file is redirected:
RedirectMatch ([\w\d\s\/\-\:\_%\ ]*\.(?!php|htm|html)) $1 [L]
CodePudding user response:
I found the solution after reviewing the error logs on my server. My various attempts were causing redirect loops. Here is my working .htaccess
file in case it helps anyone trying to do something similar.
The key is to short circuit the .htaccess
file when necessary so it doesn't keep rewriting your URLs infinitely. I added inline comments to explain the process:
# Redirect all requests to the public directory.
<IfModule mod_rewrite.c>
RewriteEngine On
# Only needing for local develoment in my case.
RewriteBase /BU/cs-602/developer-story/
# If nothing or an index page is requested go to `public/index.php` and stop processing.
RewriteRule ^(\/||.*index\..*)$ public/index.php [L,QSA]
# If the URL already contains the `public/` directory go to URL and stop processing.
RewriteRule ^(.*public\/.*)$ $1 [L,QSA]
# If it appears this URL is for a resource (JS, CSS, etc.) prefix with `public/`.
RewriteCond %{REQUEST_URI} ^([\w\d\s\-\_\/\%]*)\.(?!php|htm|html).*$
# Go to the modified URL if the last rule triggered and stop processing.
RewriteRule ^(.*)$ public/$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
# Rewrite all remaing URLs to our apps MVC structure.
RewriteRule ^([\w\d\s\-\_\/\%]*)$ public/index.php?p=$1 [L,QSA]
</IfModule>