13

I am looking at the PSR-7 interfaces and thinking of a way on how to implement them.

I've also been reading this blog post. Apparently the objects that implement the PSR-7 interfaces must be immutable.

So if I implement the withProtocolVersion method from MessageInterface then it would look something like this:

public function withProtocolVersion($version)
{
    if ( $this->protocol === $version )
    {
        return $this;
    }

    $new = clone $this;
    $new->protocol = $version;
    return $new;
}

My question really is, why immutable? Why not simply do a return $this;?

It's not that I'm concerned about the amount of memory it allocates, I just really do not see any benefit in keeping it immutable.

Like the blog posts says, when you do this:

$request = $request
    ->withMethod('POST')
    ->withUrl(new Url('http://example.org/')
    ->withHeader('Content-Type', 'text/plain');

Then four copies are created, but the end result in $request is the same as when I would simply use return $this, right?

Why is the decision made to keep it immutable. So why do I have to do a clone $this? What's the benefit of it?

I'm not really getting the idea begind it.

Vivendi
  • 20,047
  • 25
  • 121
  • 196
  • 3
    The last paragraph of that section of the blog post says: _This decision has been made for sake of robustness. This apparently would "remove a whole class of bugs"._ – Barmar Jul 11 '15 at 19:12
  • 1
    @Barmar I don't really understand what he means by that. I don't really see how it would *remove a whole class of bug*. So how *would* that remove a class of bugs? You are still able to *"set"* all the properties. Only thing it does is return a new copy of the object instead of the object it self. – Vivendi Jul 11 '15 at 19:36

1 Answers1

9

I suggest you to read this document, where all the design choices are explained in detail.

In particular you should read the Why value objects? and the New instances vs returning $this sections.

The key points are the following:

In essence, modeling HTTP messages as value objects ensures the integrity of the message state, and prevents the need for bi-directional dependencies, which can often go out-of-sync or lead to debugging or performance issues.

and

These operations can be accomplished with value objects as well, with a number of benefits:

  • The original request state can be stored for retrieval by any consumer.
  • A default response state can be created with default headers and/or message body.

If you want to dig deeper, I'd recommend to look in the history of the fig mailing list (you can find it here), where there was a lot of discussion regarding the immutability of the objects

Community
  • 1
  • 1
marcosh
  • 8,780
  • 5
  • 44
  • 74
  • Thanks, currently working my way through the mailing list. But that already made me understand the ideas behind immutable request objects. – Vivendi Jul 11 '15 at 21:21
  • 4
    I don't see reasons in the links provided. the fact that this direct question is not answered directly but with some links and the same vague opinions. Opinions about possible misconceptions of other developers. This proofs to me, that this serious design decision is not well founded and probably based only on how php is used and behaving currently/pastly. – Summer-Sky Sep 27 '16 at 11:00