Slim (v3) 群组功能中的访问请求
Slim (v3) Access Request in Group Function
让 Slim (v3) 组像:
$app->group('/user/{user_id}', function(App $app) {
// HERE
$app->get('/stuff', function(Request $request, Response $response) {
$userId = $request->getAttribute('user_id');
// ... get stuff of user
});
$app->get('/otherstuff', function(Request $request, Response $response) {
$userId = $request->getAttribute('user_id'); // repetition!
// ... get other stuff of user
});
});
有没有办法访问组函数中的 $request
(以及 URL 参数),以避免每个函数中的冗余重复?
您可以通过容器访问 group()
方法中的 $request
对象。
$req = $app->getContainer()->get('request');
但是当你使用getAttribute()
方法时你会得到NULL
。在您的情况下,不应使用从容器中检索到的请求,因为如果需要,可以 更改 请求的状态。
Request and Response 对象是不可变的。这些属性可能会有所不同,具体取决于您何时获得 Request 对象。 finished Request 对象将在您最后的操作中移交。所以,在你的行动中使用它。
然而你仍然可以获得路径并获取 user_id
的 URL 参数。
$path = $req->getUri()->getPath();
$user_id = explode('/', $path)[2];
话虽如此,group()
方法旨在帮助您将路由组织成逻辑组。如果你想 DRY up 你的代码,创建一个包含你需要的操作的 class。例如:
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Container\ContainerInterface;
class UserController
{
protected $container;
protected $userId;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->userId = $this->user();
}
public function stuff(Request $request, Response $response)
{
// Use $this->userId here
}
public function otherStuff(Request $request, Response $response)
{
// Use $this->userId here
}
protected function user()
{
$path = $this->container->get('request')->getUri()->getPath();
$parts = explode('/', $path);
return $parts[2] ?? '';
}
}
然后,更新您的路线:
$app->group('/user/{user_id}', function(App $app) {
$app->get('/stuff', UserController::class . ':stuff');
$app->get('/otherstuff', UserController::class . ':otherStuff');
});
或者,您可以从路由参数中获取$user_id
:
class UserController
{
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function stuff(Request $request, Response $response, array $args)
{
// Use $args['user_id'] here
}
public function otherStuff(Request $request, Response $response, array $args)
{
// Use $args['user_id'] here
}
}
或者如果您更喜欢闭包:
$app->group('/user/{user_id}', function(App $app) {
$app->get('/stuff', function(Request $request, Response $response, array $args) {
// Use $args['user_id'] here
});
$app->get('/otherstuff', function(Request $request, Response $response, array $args) {
// Use $args['user_id'] here
});
});
让 Slim (v3) 组像:
$app->group('/user/{user_id}', function(App $app) {
// HERE
$app->get('/stuff', function(Request $request, Response $response) {
$userId = $request->getAttribute('user_id');
// ... get stuff of user
});
$app->get('/otherstuff', function(Request $request, Response $response) {
$userId = $request->getAttribute('user_id'); // repetition!
// ... get other stuff of user
});
});
有没有办法访问组函数中的 $request
(以及 URL 参数),以避免每个函数中的冗余重复?
您可以通过容器访问 group()
方法中的 $request
对象。
$req = $app->getContainer()->get('request');
但是当你使用getAttribute()
方法时你会得到NULL
。在您的情况下,不应使用从容器中检索到的请求,因为如果需要,可以 更改 请求的状态。
Request and Response 对象是不可变的。这些属性可能会有所不同,具体取决于您何时获得 Request 对象。 finished Request 对象将在您最后的操作中移交。所以,在你的行动中使用它。
然而你仍然可以获得路径并获取 user_id
的 URL 参数。
$path = $req->getUri()->getPath();
$user_id = explode('/', $path)[2];
话虽如此,group()
方法旨在帮助您将路由组织成逻辑组。如果你想 DRY up 你的代码,创建一个包含你需要的操作的 class。例如:
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Container\ContainerInterface;
class UserController
{
protected $container;
protected $userId;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->userId = $this->user();
}
public function stuff(Request $request, Response $response)
{
// Use $this->userId here
}
public function otherStuff(Request $request, Response $response)
{
// Use $this->userId here
}
protected function user()
{
$path = $this->container->get('request')->getUri()->getPath();
$parts = explode('/', $path);
return $parts[2] ?? '';
}
}
然后,更新您的路线:
$app->group('/user/{user_id}', function(App $app) {
$app->get('/stuff', UserController::class . ':stuff');
$app->get('/otherstuff', UserController::class . ':otherStuff');
});
或者,您可以从路由参数中获取$user_id
:
class UserController
{
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function stuff(Request $request, Response $response, array $args)
{
// Use $args['user_id'] here
}
public function otherStuff(Request $request, Response $response, array $args)
{
// Use $args['user_id'] here
}
}
或者如果您更喜欢闭包:
$app->group('/user/{user_id}', function(App $app) {
$app->get('/stuff', function(Request $request, Response $response, array $args) {
// Use $args['user_id'] here
});
$app->get('/otherstuff', function(Request $request, Response $response, array $args) {
// Use $args['user_id'] here
});
});