Slim (v3) запрос доступа в групповой функции - PullRequest
0 голосов
/ 28 января 2020

Пусть существует группа 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) в функции группы , чтобы избежать избыточных повторений в каждой функции?

1 Ответ

2 голосов
/ 08 февраля 2020

Вы можете получить доступ к объекту $request в методе group() через контейнер.

$req = $app->getContainer()->get('request');

Но вы получите NULL при использовании метода getAttribute(). В вашем случае запрос, извлеченный из контейнера, не должен использоваться, поскольку состояние запроса может быть изменено при необходимости.

Запрос и Ответ объекты неизменны. Атрибуты могут варьироваться в зависимости от того, когда вы получаете объект запроса. закончен Объект запроса будет передан в вашем действии в конце. Итак, используйте его в своих действиях.

И все же вы можете получить путь и получить URL-параметр user_id.

$path = $req->getUri()->getPath();
$user_id = explode('/', $path)[2];

Как говорится, метод group() предназначен для того, чтобы помочь вам организовать маршруты в логические группы. Если вы хотите DRY улучшить свой код, создайте класс с необходимыми вам действиями. Например:

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