Reputation: 555
I know this kind of question is recurrent. But after several hours of searching I didn't find anything.
I'm making a website using Slim. However, in their documentation, they use /public
as root directory, which I don't want. I want the website root to be /
. Quite concerned about security, I created a .htaccess
to redirect http://www.example.com/
to http://www.example.com/public/
, so no user can reach /src
and other folders :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^$ /public [P]
</IfModule>
This causes a problem : the URI remains /public/
, therefore the public/index.php
file below returns a 404 error :
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
$app->get('/', function (Request $request, Response $response, $args) {
$response->getBody()->write("Hello world!");
return $response;
});
$app->run();
I have to replace '/'
with '/public/'
in the code for the page to work. I don't exactly like that.
What should I add to Slim's /public/.htaccess
below to remove the /public
from the URI ?
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
</IfModule>
I redirected my vhost to /public/
. The web hosting service I use supports this, so it's the best solution.
Upvotes: 2
Views: 780
Reputation: 45829
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^$ /public [P] </IfModule>
This only "forwards" requests for the root / homepage, ie. /
, not /foo
, etc. This also forwards the request using mod_proxy (as a reverse proxy), whereas you only need a simple internal rewrite.
You need to rewrite every request that would otherwise go to the root directory (outside of /public
) to the /public
subdirectory. ie. /foo
rewrites to /public/foo
and /images/bar.jpg
to /public/images/bar.jpg
, etc.
RewriteEngine On
RewriteRule (.*) /public/$1 [L]
(No need for the <IfModule>
wrapper since mod_rewrite is mandatory here, it's not optional.)
All your URLs (to everything) should then omit the /public
subdirectory.
UPDATE: However, it would seem that the BASE
environment variable is still being set to the /public
subdirectory by the following directives in /public/.htaccess
:
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$ RewriteRule ^(.*) - [E=BASE:%1]
You could simply comment out (remove) the above directives and hardcode the BASE
env var:
SetEnv BASE /
However, it's unclear whether this would be a problem or not in the Slim framework. It's possible that this is being used to construct URLs (although it shouldn't, since this is the filesystem path, not the URL-path by which users access the pages - and can easily be calculated in PHP anyway).
Alternatively, everything in /public
should be in your document root (ie. your public directory... public_html
or htdocs
etc.) then the /src
(and other folders) will naturally be outside the document root and no additional directives / .htaccess
files required to root the request. (Although not every shared server may give you access to above the document root - although they should.)
Or, simply change the DocumentRoot
to /public
in your server config.
Upvotes: 1