Why do routes have $args param and $request->getAttribute()?

The docs here: https://www.slimframework.com/docs/objects/router.html
… say that a route handler accepts 2 args, but the example code shows 3 ($args). Then throughout the rest of that docs page, most of the time it retrieves the args via $request->getAttribute('argname') – except for a few places where it retrieves it via $args['argname'].

Is there an intentional architectural decision here as to why there are two different ways to achieve the same thing? Is one approach better than the other under certain circumstances? If it’s just an example of “there’s more than one way to do it”, what’s the idiomatic “Slim Way” that most people use?

Thanks!

1 Like

The two arguments is referring to the [1] route pattern and then [2] the callback. The callback in those examples is itself accepting three arguments, typically $request, $response, $args.

I suspect, but have know way of knowing, that most people use $args['id'] as it is a bit shorter to type. I typically use $request->getAttribute('id') to get things from the request body, or things I’ve manually added to the request using $request->withAttribute('thing').

1 Like

Hello @jordanlev,

Both $request->getAttribute('argname') and $args['argname'] will work, because the route placeholders arguments that are passed using $args in the callback are also set in $request->getAttribute().

Using $args['argname'] is however clearer in intent. $args only contains the route placeholder arguments, while $request->getAttribute() also contains values passed along by middleware and other values.

I can create a pull request to update the documentation page to use $args and not $request->getAttribute(). I can only find one instance of $request->getAttribute() on the documentation page you mentioned. Are there other pages where you found $request->getAttribute() used instead of $args?

Huh, weird – I could have sworn when I was reading that page earlier it was using $request->getAttribute() most of the time, but I see now that it’s not (and the github repo for the docs doesn’t show a recent change, so you didn’t ninja-edit it :slight_smile: )

I suppose the one place it might make sense to update is on the tutorial: https://www.slimframework.com/docs/tutorial/first-app.html ?

Thanks for the clarification (and the great framework, great docs, and great support here in the forum).

One reason someone might want to use $request->getAtrribute() is PSR-7. If the request were something other than Slim’s request, or if you swapped out Slim with another PSR-7 thingy, you woudn’t need to change from $args. Though I suspect there are few people doing it that way for that reason.

1 Like

Good call, @tflight! I still believe the documentation would benefit from using one way consistently to avoid confusion.

I created a pull request with a suggestion for improvement.

I just found out this the hard way… we shouldn’t use the same key name for an $args and $request->getAttribute(). I didn’t realize that URI args get pushed as attributes, so I was manually adding an attribute called “my_id” from a middleware, and some of my routes also included a URI args with “my_id”, like so “/users/{my_id}”. Needless to say, my_id's value got overwritten by the URI arg, and things went wrong :smiley: . Was this just me making a rookie mistake? Or could the docs benefit from a little warning?