-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Slim 3.0 Getting Route Params in Middleware #1505
Comments
I think I've figured out a solution to my problem; however, I still would like to know how a middleware would access router parameters or what people think on that being poor middleware design For now I'm just doing the __call() magic method on my controller and making my show action private. Something like: $app->group('/users', function () {
$controller = new MyController();
$this->get('/', [$controller, 'index']);
$this->get('/{id}', [$controller, 'show']);
}); class MyController
{
public function __call($name, array $arguments)
{
list($request, $response, $args) = $arguments;
$user = $userMapper->findById($args['id']);
if ($user) {
$request = $request->withAttribute('user', $user);
return call_user_func([$this, $name], $request, $response, $args);
} else {
// $response now contains 404 response, don't call method
return $response;
}
}
private function show(ServerRequestInterface $request, ResponseInterface $response, array $args)
{
$user = $request->getAttribute('user'); // already loaded by middleware
return $response->getBody()->write(json_encode($user)); // varies, but for example
}
} |
You'll find the route parameters in the third element of the 'routeInfo' attribute. We'd love a PR documenting this :) $routeParams = $request->getAttribute('routeInfo')[2]; |
As a side note, this option does not work for application middleware |
Agree with @bradynpoulsen that it doesn't work for middleware. Would also be able to access route arguments from within middleware |
By default, the route hasn't been worked out when app middleware is running, which is why it's not working for you. If you need this, then you can enable this setting: $settings = [
'settings' => [
'determineRouteBeforeAppMiddleware' => true,
],
];
$app = new Slim\App($settings); |
@akrabat - this does solve the problem. Thanks! |
This works @kevinmlong: $settings = [
'settings' => [
'determineRouteBeforeAppMiddleware' => true,
],
];
$app = new \Slim\App($settings);
$app->get("/{name}", function ($request, $response, $args) {
return $response->write("Hello {$args['name']}");
});
$app->add(function ($request, $response, $next) {
var_dump($request->getAttribute('routeInfo')[2]);
return $next($request, $response);
}); Navigating to
|
@akrabat - I sent the other comment to quickly. I suppose I deleted it after you saw it. Thanks! A related issue .... In my middleware, I am calling $next($request,$response);
-- doing stuff -- As it goes through the routing methods, it returns a response. In some cases it changes the status to a different code (e.g. 400) like below: $newResponse = $this->response->withStatus(404)
->withHeader('Content-Type', 'application/json')
->write(...stuff...);
return $newResponse; when the application returns to the middleware, the response object has a code of 200. When returned, it has the right body, but the wrong status. Thoughts? |
@kevinmlong |
It's in the route method $app->get('path to route', function ($request, $response, $args) {
do some stuff
$newResponse = $this->response->withStatus(404)
->withHeader('Content-Type', 'application/json')
->write(...stuff...);
return $newResponse;
} The code then returns to the middleware. The code response here is 200 instead of 404. If I return the response, I get the right body from the |
@kevinmlong you need to use $app->get('path to route', function ($request, $response, $args) {
return $response->withStatus(404)
->withHeader('Content-Type', 'application/json')
->write(...stuff...);
}); |
@silentworks - that doesn't work. it still returns to the middleware with a 200 code. |
@silentworks - the response object is getting updated, since the body is being updated correctly. |
@silentworks - I figured it out. Need to change the middleware to: public function __invoke($request, $response, $next){
// do some stuff
$newResponse = $next($request,$response);
// do more stuff
return $newResponse;
} |
Add following line in configuration In middleware |
I am creating a controller class and trying to add a method on my controller to load a object based on its route ID. I've got that all written and ready to work EXCEPT I don't know how to grab the route parameters from the request. There's also no documented way for middleware to access those parameters.
The text was updated successfully, but these errors were encountered: