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
    });
});