在子目录中托管一个Slim微型站点


Host a Slim microsite in a subdirectory

有没有一种很好且受支持的方法来定义这样的路线:

$app->get('/', function (Request $request, Response $response) {
});
$app->get('/hello/{name}', function (Request $request, Response $response) {
});

无论index.php路由文件的位置如何,都能让它们按预期工作?

例如,如果DOCUMENT_ROOTC:'Projects'Playgroundhttp://playground.example.com),并且我的路由器文件位于C:'Projects'Playground'PHP'Slim'foo'bar'index.phphttp://playground.example.com/PHP/Slim/foo/bar),我希望http://playground.example.com/PHP/Slim/foo/bar/hello/world!'/hello/{name}'匹配。

(所有属于Slim的其他文件都会在其他地方,比如C:'Libraries'Slim,应该与这个问题无关。)

有了好的和支持我的意思不是这个:

$uri_prefix = complex_function_to_calculate_it($_SERVER['DOCUMENT_ROOT'], __DIR__);
$app->get($uri_prefix . '/hello/{name}', function (Request $request, Response $response) {
});

Slim 3使用nikic/快速路线,但我找不到任何提示。

除了在子目录中创建.htaccess文件

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

您需要配置web服务器或精简:

解决方案1(配置apache):

在debian 9上打开以下文件:

/etc/apache2/apache2.conf

打开后,修改

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

进入

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

然后重新启动apache以应用更改:

systemctl restart apache2

解决方案2(配置精简版):

附上这个:

// Activating routes in a subfolder
$container['environment'] = function () {
    $scriptName = $_SERVER['SCRIPT_NAME'];
    $_SERVER['SCRIPT_NAME'] = dirname(dirname($scriptName)) . '/' . basename($scriptName);
    return new Slim'Http'Environment($_SERVER);
};

请注意,您需要在路由中使用subdir名称,例如/subdir/表示home,或一些特定的路由:/subdir/auth/signup

哦。。。如果它没有开箱即用的支持,我想最好不要把它复杂化,把它作为一个参数:

define('ROUTE_PREFIX', '/PHP/Slim/foo/bar');
$app->get(ROUTE_PREFIX . '/hello/{name}', function (Request $request, Response $response) {
});

毕竟,编写在任何情况下都能动态计算的通用代码都是一种负担,尤其是当你可能有无数的因素,比如符号链接或Apache别名时。

当然,该参数应该与站点的其他设置一起定义(如果使用Slim Skeleton,则为src/settings.php,如果使用phpdotenv,则为.env…等等)。

您可以将所有路由嵌套在Slim中的包装器组中,该包装器组的路径模式是基于$_SERVER变量确定的:

$app = Slim'Factory'AppFactory::create();
$app->group(dirname($_SERVER['SCRIPT_NAME']), function($subdirectory) {
    $subdirectory->group('/api/v1', $function($api) {
        // define routes as usual, e.g...
        $api->get('/foo/{foo:[0-9]+}', function($req, $res) {
            // ...
        });
    });
});

$_SERVER['SCRIPT_NAME']变量进行一点预处理可以做其他事情——例如,检测API是否嵌套在名为API的目录中,并且不要将另一个API附加到路由模式。