On Thu, Dec 29, 2016 at 7:16 AM, Rasmus Schultz <
ras...@mindplay.dk> wrote:
> Reading through those comments, I am if anything now more baffled.
>
> Looking at an implementation of attach() such as zend-diactoros, the
> implementation of attach() is precisely identical to that of __construct() -
> it effectively permits you to replace the entire object with a different
> object, e.g. provides a kind of mutability that enables you to replace the
> entire object.
>
> As far as I can figure, the only thing you can hope to accomplish with that,
> is side-effects - a degree of side-effects not even possible with native
> streams.
>
> And we wanted to avoid side-effects, right? That's why the rest of the model
> is immutable.
>
> Can you point me to a real-world example of attach() and detach() in use?
attach() exists in zend-diactoros because the library was developed in
tandem with PSR-7 development. Unfortunately, the method was never
removed. I plan to do so in the next major revision, and will be
marking it as deprecated in an upcoming minor release. Please ignore
the method when considering PSR-7; we omitted it from the spec for a
number of reasons.
First, as you note, it goes against the design of the rest of the
specification, which strives for immutability. Second, replacing the
underlying resource is something that is untenable: not all stream
implementations will be backed with the same type of resource, making
implementation essentially impossible. As an example, while the target
implementation is a PHP stream resource, we have also allowed for
callback, generator, and iterator-backed stream. What happens if you
provide one of these to an implementation that only supports PHP
streams? or a PHP stream to an implementation that expects a callback?
As such, we removed attach() from the spec. As I've also noted, I
neglected to remove it from Diactoros when that change happened. It's
not part of the spec; as a PSR-7 consumer, it's something you can
safely ignore.
The reason for having detach() was to allow access to the underlying
resource in order to perform operations not supported by the
interface. As an example, if you want to use stream_copy_to_stream()
to copy the stream to PHP's php://output stream more performantly, or
to copy an incoming stream to an HTTP client request stream, you would
need access to the underlying resource. Similarly, if you wanted to
use iterator_to_array() to cast an iterator- or generator-backed
stream to an array, you could pull the underlying resource. detach()
is _destructive_, however, because any such manipulations could
themselves alter the behavior of the underlying resource associated
with the StreamInterface. As an example, a read-only stream, when
read, would leave the StreamInterface implementation in unusable
state.
Hopefully the above helps clarify the purpose of detach(), and why
attach() was removed from the specification.
>
https://groups.google.com/d/msgid/php-fig/08a6b4ab-fcec-4ccc-8b0f-351cdf3612cd%40googlegroups.com.
--
Matthew Weier O'Phinney
mweiero...@gmail.com
https://mwop.net/