如何使用 Slim Framework 转发 HTTP 请求
How to forward an HTTP request with Slim Framework
是否可以在 Slim 中转发一个请求?
"forward"的意思,和JavaEE一样,是内部重定向到另一个路由,而不return响应客户端和维护模型。
例如:
$app->get('/logout',function () use ($app) {
//logout code
$app->view->set("logout",true);
$app->forward('login'); //no redirect to client please
})->name("logout");
$app->get('/login',function () use ($app) {
$app->render('login.html');
})->name("login");
我认为你必须重定向它们。斯利姆没有前锋。但是您可以在重定向功能中设置状态代码。当您重定向到一条路线时,您应该获得您想要的功能。
// With route
$app->redirect('login');
// With path and status code
$app->redirect('/foo', 303);
这是文档中的示例:
<?php
$authenticateForRole = function ( $role = 'member' ) {
return function () use ( $role ) {
$user = User::fetchFromDatabaseSomehow();
if ( $user->belongsToRole($role) === false ) {
$app = \Slim\Slim::getInstance();
$app->flash('error', 'Login required');
$app->redirect('/login');
}
};
};
有redirect()
方法。但是它会发送一个你不想要的 302 Temporary Redirect
响应。
$app->get("/foo", function () use ($app) {
$app->redirect("/bar");
});
另一种可能性是pass()
,它告诉应用程序继续下一个匹配的路由。当 pass()
被调用时,Slim 会立即停止处理当前匹配的路由并调用下一个匹配的路由。
如果没有找到后续匹配的路由,则向客户端发送一个404 Not Found
。
$app->get('/hello/foo', function () use ($app) {
echo "You won't see this...";
$app->pass();
});
$app->get('/hello/:name', function ($name) use ($app) {
echo "But you will see this!";
});
在我看来,最好的方法是使用 Slim 的内部路由器 (Slim\Router
) capabilities and dispatching (Slim\Route::dispatch()
) 匹配的路由(意思是:从匹配的路由执行可调用而无需任何重定向)。我想到了几个选项(取决于您的设置):
1。调用命名路由 + 可调用不带任何参数(你的例子)
$app->get('/logout',function () use ($app) {
$app->view->set("logout",true);
// here comes the magic:
// getting the named route
$route = $app->router()->getNamedRoute('login');
// dispatching the matched route
$route->dispatch();
})->name("logout");
这绝对可以满足您的需求,但我仍想展示其他场景...
2。调用命名路由+可调用参数
上面的例子会失败...因为现在我们需要将参数传递给可调用对象
// getting the named route
$route = $app->router()->getNamedRoute('another_route');
// calling the function with an argument or array of arguments
call_user_func($route->getCallable(), 'argument');
调度路由(使用 $route->dispatch())将调用所有中间件,但这里我们只是直接调用可调用对象...所以要获得完整的包,我们应该考虑下一个选项.. .
3。调用任意路由
如果没有命名路由,我们可以通过查找与 http 方法和模式匹配的路由来获取路由。为此,我们使用 Router::getMatchedRoutes($httpMethod, $pattern, $reload)
并将重新加载设置为 TRUE
.
// getting the matched route
$matched = $app->router()->getMatchedRoutes('GET','/classes/name', true);
// dispatching the (first) matched route
$matched[0]->dispatch();
在这里你可能想要添加一些检查,例如 dispatch notFound
以防没有匹配的路由。
我希望你明白 =)
是否可以在 Slim 中转发一个请求? "forward"的意思,和JavaEE一样,是内部重定向到另一个路由,而不return响应客户端和维护模型。
例如:
$app->get('/logout',function () use ($app) {
//logout code
$app->view->set("logout",true);
$app->forward('login'); //no redirect to client please
})->name("logout");
$app->get('/login',function () use ($app) {
$app->render('login.html');
})->name("login");
我认为你必须重定向它们。斯利姆没有前锋。但是您可以在重定向功能中设置状态代码。当您重定向到一条路线时,您应该获得您想要的功能。
// With route
$app->redirect('login');
// With path and status code
$app->redirect('/foo', 303);
这是文档中的示例:
<?php
$authenticateForRole = function ( $role = 'member' ) {
return function () use ( $role ) {
$user = User::fetchFromDatabaseSomehow();
if ( $user->belongsToRole($role) === false ) {
$app = \Slim\Slim::getInstance();
$app->flash('error', 'Login required');
$app->redirect('/login');
}
};
};
有redirect()
方法。但是它会发送一个你不想要的 302 Temporary Redirect
响应。
$app->get("/foo", function () use ($app) {
$app->redirect("/bar");
});
另一种可能性是pass()
,它告诉应用程序继续下一个匹配的路由。当 pass()
被调用时,Slim 会立即停止处理当前匹配的路由并调用下一个匹配的路由。
如果没有找到后续匹配的路由,则向客户端发送一个404 Not Found
。
$app->get('/hello/foo', function () use ($app) {
echo "You won't see this...";
$app->pass();
});
$app->get('/hello/:name', function ($name) use ($app) {
echo "But you will see this!";
});
在我看来,最好的方法是使用 Slim 的内部路由器 (Slim\Router
) capabilities and dispatching (Slim\Route::dispatch()
) 匹配的路由(意思是:从匹配的路由执行可调用而无需任何重定向)。我想到了几个选项(取决于您的设置):
1。调用命名路由 + 可调用不带任何参数(你的例子)
$app->get('/logout',function () use ($app) {
$app->view->set("logout",true);
// here comes the magic:
// getting the named route
$route = $app->router()->getNamedRoute('login');
// dispatching the matched route
$route->dispatch();
})->name("logout");
这绝对可以满足您的需求,但我仍想展示其他场景...
2。调用命名路由+可调用参数
上面的例子会失败...因为现在我们需要将参数传递给可调用对象
// getting the named route
$route = $app->router()->getNamedRoute('another_route');
// calling the function with an argument or array of arguments
call_user_func($route->getCallable(), 'argument');
调度路由(使用 $route->dispatch())将调用所有中间件,但这里我们只是直接调用可调用对象...所以要获得完整的包,我们应该考虑下一个选项.. .
3。调用任意路由
如果没有命名路由,我们可以通过查找与 http 方法和模式匹配的路由来获取路由。为此,我们使用 Router::getMatchedRoutes($httpMethod, $pattern, $reload)
并将重新加载设置为 TRUE
.
// getting the matched route
$matched = $app->router()->getMatchedRoutes('GET','/classes/name', true);
// dispatching the (first) matched route
$matched[0]->dispatch();
在这里你可能想要添加一些检查,例如 dispatch notFound
以防没有匹配的路由。
我希望你明白 =)