Я использую сборку контроллера/промежуточного программного обеспечения с тонким 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());
Мой вариант использования - отправлять вещи во все представления, отображаемые действиями этих контроллеров, поэтому я также согласен с другими способами сделать это :)
Спасибо.






поэтому вам нужно просто передать данные из промежуточного программного обеспечения в контроллер
что о
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');
//...
}
}
используйте мое предложенное решение + затем посмотрите на InvocationStrategyInterface и реализуйте свою собственную стратегию вызова, которая будет собирать данные из запроса и передавать вам это магическое значение из запроса как часть параметра Args (в основном вам нужно использовать свою собственную реализацию \Slim \Handlers\Strategies\RequestResponseArgs ) - в основном вы будете делать это array_merge в реализации InvocationStrategyInterface :)
Ага.... не знал об этом. Попробую, а там как получится :) Спасибо за идею.
Спасибо, это работает :) Чтобы добавить некоторую информацию о том, как я его использовал: я добавил класс MyRequestResponse extends RequestResponseArgs, который делает что-то в методе __invoke, а затем в контейнере: $container['foundHandler'] = function ($container){ вернуть новый MyRequestResponse(); };
Для полноты я собираюсь расширить отличный ответ, данный @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.
Это полезно для таких задач, как контроль доступа, когда я всегда хочу загружать роли пользователей перед обработкой запроса, но я уверен, что для этого будет много других вариантов использования.
Надеюсь, это кому-нибудь поможет.
я знаю об этом... но в основном мне нужно добавить к каждому действию в этом контроллере $yourAttributeFromMiddleware = $request->getAttribute('myMagicArgument'); и вернуть $this->container->get('renderer')->render($response, "index.html.twig", array_merge($args, $yourAttributeFromMiddleware));