PHP-DI / Slim-Bridge

PHP-DI integration with the Slim framework
http://php-di.org/doc/frameworks/slim.html
MIT License
175 stars 38 forks source link

Support for typed route parameters #69

Open fabiante opened 3 years ago

fabiante commented 3 years ago

Hi!

I'd like to use php-di to inject route parameters. In my case these are always of type int.

Using this function signature ...


$app->delete("/objects/{objectId}", [MyController::class, 'deleteObject']); // Please ignore the fake callable setup, this is just for demonstration

// ...

public function deleteObject(Request $request, Response $response, int $objectId)

... and then calling the path of this function with this URL: DELETE /objects/testing/ ...

... produces a standard PHP exception: Argument 4 passed to App\\Controllers\\v2\\DocumentClassController::deleteTableField() must be of the type int, string given

I do understand why this happens and of course I could remove the int type from the function signature and perform my own validation. But' maybe I am missing a more elegant way to catch this exception and automatically respond with a 400 status code.

Rarst commented 3 years ago

I think in Slim mechanics it would make sense to restrict the route to numeric IDs, so invalid value doesn't even match/reach controller:

$app->delete("/objects/{objectId:[0-9]+}", [MyController::class, 'deleteObject']);

See regular expression matching.

You'll get an automatic native 404 from Slim, for anything that doesn't match.

Not sure how invocation could be any "smarter" about such. I think it's already better than native Slim for types (Slim wouldn't even cast input to int, if I remember right).

nixoncode commented 3 years ago

This is definitely not an issue that concerns Slim-Brige the solution above by @Rarst of using regular expression matching is the way to do it, as it's the framework way and will be handled by the RouteParser.

solventt commented 2 years ago

@FabianTe What you want is solved by writing an invocation route strategy, see the Slim docs. If you dont want to learn the Slim internals - you can use my component for the Slim (https://github.com/solventt/slim-route-strategy) - It also solves your problem: a numeric $id argument has an integer type when it comes in a controller method signature. BUT there is only one condition - the name of the controller parameter and the route placeholder MUST be id.