Closed G4MR closed 8 years ago
See: http://www.slimframework.com/docs/concepts/middleware.html
Slim adds middleware as concentric layers surrounding your core application. Each new middleware layer surrounds any existing middleware layers. The concentric structure expands outwardly as additional middleware layers are added.
LIFE: Last In First Executed
Thanks for the response @mathmarques, clears that up. Though I wish there was a way to reverse it from inner to outer.
Though I wish there was a way to reverse it from inner to outer.
@G4MR Why? Maybe I'm too used to the onion style, but it makes perfect sense to me:
$app->group('/product/{id:[0-9]+}', function () {
$this->get('', function ($request, $response, $args) {
// no auth needed
});
$this->delete('', function ($request, $response, $args) {
// auth needed
})->add($injector->make(Authenticated::class));
})->add($injector->make(SomeMiddleware::class));
@schnittstabil options are nice
LIFE: Last In First Executed
I'd like to suggest adding that to the docs. Thinking in terms of concentric layers, I would expect to be able to do the following:
<?php
require 'vendor/autoload.php';
$app = new \Slim\App();
$app->add(function ($request, $response, $next) {
$response->getBody()->write(' Foo ');
return $next($request, $response);
});
$app->get('/', function ($req, $res, $args) {
echo ' Bar ';
});
$app->add(function ($request, $response, $next) {
$response->getBody()->write(' Baz ');
return $next($request, $response);
});
$app->run();
and get Foo Bar Baz
as a result, but instead get Baz Foo Bar
. To get my desired result, and effectively ensure that I can guarantee that a specific middleware is executed last, I need to do:
<?php
require 'vendor/autoload.php';
$app = new \Slim\App();
$app->add(function ($request, $response, $next) {
$response = $next($request, $response);
$response->getBody()->write(' Baz ');
return $response;
});
$app->get('/', function ($req, $res, $args) {
echo ' Bar ';
});
$app->add(function ($request, $response, $next) {
$response->getBody()->write(' Foo ');
return $next($request, $response);
});
$app->run();
@betweenbrain Slim also supports:
$app->add(function ($request, $response, $next) {
return $next($request, $response)->write(' Baz ');
});
$app->get('/', function ($req, $res, $args) {
return $res->write(' Bar ');
});
Don't ever echo
. Return the $response
with the additional text that you want.
First things first, $app->get | post | put | map | ... will always be the first layer(so it will always be the last executed). Slim have App level Middlewares and Route level Middlewares, and app level middlewares are always executed first than route level middleware.
If you take a look here: https://github.com/slimphp/Slim/issues/1622 (now slim execute order is what I was expecting) I think you could understand better how this works.
@schnittstabil thanks! That's a great tip.
@akrabat the example code I cited is based on the example at http://www.slimframework.com/docs/concepts/middleware.html#application-middleware. I'll create a PR against Slim-Website to correct it.
I'll also include the addition of LIFE: Last In First Executed as I think that's an import statement to make as it very eloquently sums up the middleware execution order.
So I've been testing some code and I've noticed my middleware is being called out of order for example:
When I load the page it calls
Authenticated::class
before SomeMiddleware. Is this a bug or intended because that doesn't make sense. I wanted to write it like so originally:Kind of odd :/