# Response with attribute

**URL:** <https://discourse.slimframework.com/t/response-with-attribute/1371>\
**Category:** Questions\
**Created:** [April 5, 2017, 2:07pm UTC](https://discourse.slimframework.com/t/response-with-attribute/1371 "2017-04-05T14:07:16Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Senshi](https://avatars.discourse-cdn.com/v4/letter/s/e480ec/32.png) [@Senshi](https://discourse.slimframework.com/u/Senshi)\
**Post date:** [April 5, 2017, 2:07pm UTC](https://discourse.slimframework.com/t/response-with-attribute/1371/1 "2017-04-05T14:07:17Z")

</div>

I’m using some middlewares, and I would like to pass arguments on the backleg.

Meaning: I would like the equivalent of $request-\>setAttribute(), e.g. $response-\>setAttribute() . However, such a function does not exist.

How can I send information to my outer middlewares? The only thing that is returned is the $response, and I don’t see anything that would allow this. I guess I could “hijack” the header/body to set these attributes, then unset them in the outbound middleware, but that seems hardly ideal.

Any ideas for a better solution?

---

<div class="post-metadata">

**Author:** ![tflight](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/tflight/32/1205_2.png) [@tflight](https://discourse.slimframework.com/u/tflight)\
**Post date:** [April 5, 2017, 3:28pm UTC](https://discourse.slimframework.com/t/response-with-attribute/1371/2 "2017-04-05T15:28:11Z")

</div>

Yes, you can do this with the [Request object](https://github.com/slimphp/Slim/blob/3.x/Slim/Http/Request.php#L946) as it follows [PSR-7](http://www.php-fig.org/psr/psr-7/). You are passing both the `Request` and `Response` along to the next callable. In your middleware, you would do

```php
public function __invoke(Request $request, Response $response, $next)
{
    $request = $request->withAttribute('foo', 'bar');
    $response = $next($request, $response);
    return $response;

```

Then later in your app (or in later middleware) you can retrieve it from `Request` again.

```php
$foo = $request->getAttribute('foo'); // bar

```

---

<div class="post-metadata">

**Author:** ![Senshi](https://avatars.discourse-cdn.com/v4/letter/s/e480ec/32.png) [@Senshi](https://discourse.slimframework.com/u/Senshi)\
**Post date:** [April 5, 2017, 4:13pm UTC](https://discourse.slimframework.com/t/response-with-attribute/1371/3 "2017-04-05T16:13:59Z")

</div>

I failed at making sense in my OP, I see 🙂

I can’t use $request, because I’m on my way out of the route already.  
MW (middleware)  
MW1 -\> MW2 -\> MW3 -\> route (here I want to set an attribute) -\> MW3 -\> MW2 -\> MW1 (here I want to get the attribute and do stuff with it) -\> response (which should then not have the attribute anymore, neither in header nor body)

As the middlewares only ever return the $response via $next, the $request is not updated on the way back out of the route.

---

<div class="post-metadata">

**Author:** ![tflight](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/tflight/32/1205_2.png) [@tflight](https://discourse.slimframework.com/u/tflight)\
**Post date:** [April 5, 2017, 5:09pm UTC](https://discourse.slimframework.com/t/response-with-attribute/1371/4 "2017-04-05T17:09:22Z")

</div>

Yes, I misunderstood, sorry.

---

<div class="post-metadata">

**Author:** ![Senshi](https://avatars.discourse-cdn.com/v4/letter/s/e480ec/32.png) [@Senshi](https://discourse.slimframework.com/u/Senshi)\
**Post date:** [April 6, 2017, 7:10am UTC](https://discourse.slimframework.com/t/response-with-attribute/1371/5 "2017-04-06T07:10:40Z")

</div>

Upon further research, it seems this is an issue with PSR-7 itself. Just googling for “PSR7 attribute on response” yields a lot of discussion threads about this particular issue (and a number of related issues). Didn’t find a clear suggestion on how to work around it, except to (mis)use the $response-\>withHeader() , so I’ll stick with that for now, but I’m very interested in better ideas 🙂 .

---

<div class="post-metadata">

**Author:** ![7ex00](https://avatars.discourse-cdn.com/v4/letter/7/ecccb3/32.png) [@7ex00](https://discourse.slimframework.com/u/7ex00)\
**Post date:** [April 4, 2023, 11:26am UTC](https://discourse.slimframework.com/t/response-with-attribute/1371/6 "2023-04-04T11:26:14Z")

</div>

Sorry for necropost, but unfortunately this is still an unfixed “issue” that comes up every once in a while.

Since response has no way to set an attribute, my way of doing it is just passing a mutable “container class” as a request attribute, and then collecting data from it after handling the request in a middleware.

```auto
public function controllerMethod($req, $res)
{
	$req->getAttribute('bag')->someAttribute = 123;

	return $this->get('view')->render('blah.html');
}

// Some middleware
$app->add(function ($req, $handler) {
	$bag = new stdClass;

    // We're storing a mutable container class in an immutable Request,
    // which kinda defeats its purpose.
	$res = $handler->handle($req->withAttribute('bag', $bag));

	if ($bag->someAttribute === 123) {
		// do something after the request
	}

    return $res;
});

```

You can also just use the DI container to store the class, without bothering at all with request and response.

**This is in no way a proper design practice! I want you to roast me and come up with something better!**

The best way would obviously be to just add attributes to a response, which is unfortunately not implemented or not PSR-compliant (which one is it?):

```auto
public function controllerMethod($req, $res)
{
	return $this->get('view')->render(
        $res->withAttribute('someAttribute', 123), 'blah.html');
}

// Some middleware
$app->add(function ($req, $handler) {
	$res = $handler->handle($req);

	if ($res->getAttribute('someAttribute') === 123) {
		// do something after the request
	}

    return $res;
});

```

---

<div class="post-metadata">

**Author:** ![odan](https://avatars.discourse-cdn.com/v4/letter/o/9de053/32.png) [@odan](https://discourse.slimframework.com/u/odan)\
**Post date:** [April 4, 2023, 2:52pm UTC](https://discourse.slimframework.com/t/response-with-attribute/1371/7 "2023-04-04T14:52:51Z")

</div>

Welcome @7ex00

> Since response has no way to set an attribute…

~~I would argue that this assertion is incorrect, since you can set an attribute as (already) mentioned above.~~

Update: Only PSR-7 request interface contains methods to set attributes:

> The server request provides one additional property, “attributes”, to allow consumers the ability to introspect, decompose, and match the request against application-specific rules (such as path matching, scheme matching, host matching, etc.). As such, the server request can also provide messaging between multiple request consumers.

Yes, the PSR-7 response interface contains no methods for attributes because it is designed to represent only the HTTP response message itself, without any implementation-specific metadata or contextual information.

When following good / best practices, you would fetch additional data from your “service” or from the request etc. and pass it as array or object to your use-case specific renderer, e.g. html template render or JSON renderer etc. So there is no need to use the response object for such kind of “meta” data.
