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.
PSR-7 is a set of common interfaces defined by PHP Framework Interop Group. These interfaces are representing HTTP messages, and URIs for use when communicating trough HTTP. Any web application using this set of interfaces is a PSR-7 application.
PSR-15 HTTP Middleware describes a common standard for HTTP middleware components using HTTP Messages defined by PSR-7. Currently, PSR-15 is a PHP Standards Recommendation of the Framework Interoperability Group (FIG).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With