Slim 3框架-将数据从中间件传递到控制器-动作args

时间:2019-07-13 13:11:06

标签: php controller action middleware 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());

我的用例是将东西发送到这些控制器的动作所呈现的所有视图,所以我也可以通过其他方式做到这一点:)

谢谢。

2 个答案:

答案 0 :(得分:1)

出于完整性考虑,我将给出@jDolba给出的出色答案

不幸的是,尽管它使我朝着正确的方向前进,但仍然需要进行一些尝试才能使一切正常运行。

基本上,如slim router docs

中所述
  

路由回调签名由路由策略确定。通过   默认情况下,Slim希望路由回调能够接受请求,响应,   以及一组路由占位符参数。这称为   RequestResponse策略。但是,您可以更改预期的路线   只需使用其他策略即可进行回调签名。作为一个   例如,Slim提供了一种替代策略,称为   接受请求和响应以及每个路由的RequestResponseArgs   占位符作为单独的参数。这是使用此示例   替代策略;只需替换foundHandler依赖项   由默认#!/usr/bin/env python # -*- coding: utf-8 -*- import barcode from barcode.writer import ImageWriter def testEan(): EAN = barcode.get_barcode_class('ean13') ean = EAN(u'123456789011', writer=ImageWriter()) fullname = ean.save('my_ean13_barcode') if __name__ == '__main__': testEan() 提供:

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

但是,对于将一些标准化数据注入到\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(); }; } 。此外,这可以直接传递到任何Twig视图。

这对于诸如访问控制之类的任务很有用,在该任务中,我总是希望在处理请求之前先加载用户的角色,但是我敢肯定会有很多其他用例。

我希望这对某人有帮助。

答案 1 :(得分:0)

因此您只需要将数据从中间件传递到控制器

关于

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