无法将属性从一个中间件传递到下一个中​​间件

时间:2017-03-24 10:28:53

标签: slim

这两个中间件都是使用代码调用的路由组中间件:

$this->get( '/edit/{id}', \Rib\Src\Apps\Blog\BlogControllers\EditController::class . ':index' )
     ->add( new RequireAuth() )
     ->add( new RequireOwner() );

中间件1,看看我设置中间件属性的最后两行,就像在瘦身网站上一样:

use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;

/**
 * MiddleWare that insures that the user accessing a resource is authenticated.
 * Class RequireAuth
 * @package Rib\Src\MiddleWares
 */
class RequireAuth
{

    # Variable used to disable redirect to '/user/set-username' from itelf. That would cause infinite redirection loop.
    # This is passed to the middleWare from the list of routes. Of course only true for '/user/set-username' pages.
    private $disableUserNameValidationCheck;


    function __construct( $disableUserNameValidationCheck = false )
    {
        $this->disableUserNameValidationCheck = $disableUserNameValidationCheck;
    }


    public function __invoke( Request $request, Response $response, $next )
    {
        # User is not authenticated: we ensure this by checking his id which is necessarily set when he is logged in.
        if ( ! isset( $_SESSION[ 'id' ] ) ) {
            FlashMessages::flashIt( 'message', "The page you tried to access requires that you are logged in the site." );

            return $response->withRedirect( '/user/login' );
        }

        # In case user has logged in from a social network and has not set a user name and password. Username is 'temporary-.....'
        # We really want the user to set his username. So on designated page we force redirect to page to setup username and email.
        if ( ! $this->disableUserNameValidationCheck and isset( $_SESSION[ 'username' ] ) and strpos( $_SESSION[ 'username' ], 'temporary' ) !== false ) {
            FlashMessages::flashIt( 'message',
                "This part of the site requires that you complete your profile with a definitive username and email. Thank you for your understanding." );

            return $response->withRedirect( '/user/set-username' );
        }

        # Set in request some data so it won't be needed to fetch it from the other potential middlewares in the chain
        $request = $request->withAttribute( 'foo', 'bar' );

        # Process regular flow if not interrupted by the middleWare.
        return $next( $request, $response );
    }
}

应该获得属性的中间件2:

use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;

class RequireOwner
{
    public function __invoke( Request $request, Response $response, $next )
    {
        $foo = $request->getAttribute( 'foo' ); // null


        return $next( $request, $response );
    }

}

为什么第二个中间件的foo值为null而不是bar?

1 个答案:

答案 0 :(得分:2)

中间件最后一次执行。要执行RequireAuth,请先更改添加中间件的顺序。

$this->get('/edit/{id}', \Rib\Src\Apps\Blog\BlogControllers\EditController::class . ':index')
     ->add(new RequireOwner())
     ->add(new RequireAuth());