Bellow is my site directory structure:
htdocs/
My-Project/
.htaccess
public/
css/
img/
img.jpg
js/
index.php
...(other stuff)
I want to use an .htaccess file to check if the requested path is a file in the public/ directory (similar to serving static files from an directory in express with express.static). If yes, serve it, else forward request to /index.php.
Basically my problem can be split into the following Sub-Problems:
SubProblem1: Serve only files from public directory, else route to index.php
SubProblem2: Serve these files from public directory without (need of) ‘public’ in the URL
So /My-Project/img/img.jpg
should be rewritten to /My-Project/public/img/img.jpg
but /My-Project/notexisting.file
or /My-Project/test
should be rewritten to /My-Project/index.php
.
This was my idea so far:
RewriteEngine On
#Block 1
#Condition: File exists in public directory
RewriteCond %{DOCUMENT_ROOT}/My-Project/public/$1 -f
RewriteRule ^(.*)$ public/$1 [L]
#Block 2
#Condition: File doesn't exist in public directory
RewriteCond %{DOCUMENT_ROOT}/My-Project/public/$1 !-f
RewriteRule ^(.*)$ index.php [L,QSA]
When Block 1
stands alone -> SubProblem2 is solved, but as soon as Block 2
is added for solving SubProblem1 every Request is rewritten to index.php. Why does that happen? Why doesn’t work the second RewriteCond as expected?
2
Answers
The second RewriteCond didn't work as I expected, because as soon as Block1 rewrites the Request, $1 in Block2 doesn't contain the same Information as in Block1.
Example
Imagine we have the URI
/My-Project/img/img.jpg
.In Block1
$1
will beimg/img.jpg
. Because this file exists, the RewriteCondition would be fulfilled and the new URI will beMy-Project/public/img/img.jpg
.Now it comes to Block2: Because of the rewritten URI,
$1
is here defined aspublic/img/img.jpg
. So the RewriteCondition will check, if there is any existing File under the URLMyProject/public/public/img/img.jpg
. Of course it isn't. So the RewriteCondition will always be fulfilled and every Request will be rewritten to index.php regardless of any former Rewriting.Solution
Here’s what I use:
Then in
/etc/hosts
, I added127.0.0.1 awesome.scot
, so now I access my site in the browser withhttp://awesome.scot
Note the two folders in the vhost conf, one is the site root, one is the public directory.
If you haven’t turned vhosts on, give it a try! Uncomment the vhosts line in your apache conf, then go into the extra folder and configure your vhost, then restart!