Среда Slim 3 — передача данных из промежуточного программного обеспечения в контроллер — аргументы действия

Я использую сборку контроллера/промежуточного программного обеспечения с тонким 3, и я хочу, чтобы промежуточное программное обеспечение, прикрепленное к группе, передало некоторые данные в параметр $args в моем контроллере - действие.

Вот код:

class MyController
{
    protected $container;

    public function __construct(ContainerInterface $container) {
        $this->container = $container;
    }

    public function index(Request $request, Response $response, $args) {
        return $this->container->get('renderer')->render($response, "index.html.twig", $args);
    }
}
class MyMiddleware
{
    public function __invoke(Request $request, Response $response, $next)
    {
// do some stuff to inject further down to $args some data
        return $next($request, $response);
    }
}
$app->group('/group', function () use ($app){
//routes
    })->add(new MyMiddleware());

Мой вариант использования - отправлять вещи во все представления, отображаемые действиями этих контроллеров, поэтому я также согласен с другими способами сделать это :)

Спасибо.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
0
1 946
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

поэтому вам нужно просто передать данные из промежуточного программного обеспечения в контроллер

что о

class MyMiddleware
{
    public function __invoke(Request $request, Response $response, $next)
    {
        $request = $request->withAttribute('myMagicArgument', 42);
        return $next($request, $response);
    }
}

а потом в контроллере

class MyController
{
    //...
    public function index(Request $request, Response $response) {
        $yourAttributeFromMiddleware = $request->getAttribute('myMagicArgument');
        //...
    }
}

я знаю об этом... но в основном мне нужно добавить к каждому действию в этом контроллере $yourAttributeFromMiddleware = $request->getAttribute('myMagicArgument'); и вернуть $this->container->get('renderer')->render($response, "index.html.twig", array_merge($args, $yourAttributeFromMiddleware));

C Apetrei 24.07.2019 21:55

используйте мое предложенное решение + затем посмотрите на InvocationStrategyInterface и реализуйте свою собственную стратегию вызова, которая будет собирать данные из запроса и передавать вам это магическое значение из запроса как часть параметра Args (в основном вам нужно использовать свою собственную реализацию \Slim \Handlers\Strategies\RequestResponseArgs ) - в основном вы будете делать это array_merge в реализации InvocationStrategyInterface :)

jDolba 25.07.2019 07:06

Ага.... не знал об этом. Попробую, а там как получится :) Спасибо за идею.

C Apetrei 27.07.2019 09:16

Спасибо, это работает :) Чтобы добавить некоторую информацию о том, как я его использовал: я добавил класс MyRequestResponse extends RequestResponseArgs, который делает что-то в методе __invoke, а затем в контейнере: $container['foundHandler'] = function ($container){ вернуть новый MyRequestResponse(); };

C Apetrei 27.07.2019 09:55

Для полноты я собираюсь расширить отличный ответ, данный @jDolba

К сожалению, хотя это и заставило меня двигаться в правильном направлении, все же потребовалось немного экспериментов, чтобы все заработало.

В основном, как описано в документация по тонкому маршрутизатору

The route callback signature is determined by a route strategy. By default, Slim expects route callbacks to accept the request, response, and an array of route placeholder arguments. This is called the RequestResponse strategy. However, you can change the expected route callback signature by simply using a different strategy. As an example, Slim provides an alternative strategy called RequestResponseArgs that accepts request and response, plus each route placeholder as a separate argument. Here is an example of using this alternative strategy; simply replace the foundHandler dependency provided by the default \Slim\Container:

$c = new \Slim\Container();
$c['foundHandler'] = function() {
    return new \Slim\Handlers\Strategies\RequestResponseArgs();
};

$app = new \Slim\App($c);
$app->get('/hello/{name}', function ($request, $response, $name) {
    return $response->write($name);
});

You can provide your own route strategy by implementing the \Slim\Interfaces\InvocationStrategyInterface.

Однако, для задачи по вставке некоторых стандартизированных данных в массив $args[] класс по умолчанию \Slim\Handlers\Strategies\RequestResponse делает все, что нужно, за вычетом вставки данных.

Таким образом, я просто расширил этот класс:

<?php

namespace MyProject\Handlers\Strategies;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

use \Slim\Handlers\Strategies\RequestResponse;

class SomeNewInvocationStrategy extends RequestResponse
{
    /**
     * Invoke a route callable.
     *
     * @param callable               $callable The callable to invoke using the strategy.
     * @param ServerRequestInterface $request The request object.
     * @param ResponseInterface      $response The response object.
     * @param array                  $routeArguments The route's placholder arguments
     *
     * @return ResponseInterface|string The response from the callable.
     */
    public function __invoke( callable $callable, ServerRequestInterface $request, ResponseInterface $response, array $routeArguments)
    {
        $routeArguments['test'] = 'testing testing 123';
        return parent::__invoke( $callable, $request, $response, $routeArguments );
    }
} 

Мое объявление контейнера выглядит так:

<?php

use Slim\App;

return function (App $app) {
    $container = $app->getContainer();

    $container['foundHandler'] = function() {
        return new MyProject\Handlers\Strategies\SomeNewInvocationStrategy();
    };
}

Затем во всех действиях моего контроллера у меня есть доступ к $args['test']. Кроме того, это можно передать прямо в любое представление Twig.

Это полезно для таких задач, как контроль доступа, когда я всегда хочу загружать роли пользователей перед обработкой запроса, но я уверен, что для этого будет много других вариантов использования.

Надеюсь, это кому-нибудь поможет.

Другие вопросы по теме