Multipart Stream Builder
A multipart stream is a special kind of stream that is used to transfer files over HTTP. There is currently no PSR-7 support for multipart streams as they are considered to be normal streams with a special content. A multipart stream HTTP request may look like this:
POST / HTTP/1.1 Host: example.com Content-Type: multipart/form-data; boundary="578de3b0e3c46.2334ba3" --578de3b0e3c46.2334ba3 Content-Disposition: form-data; name="foo" Content-Length: 15 A normal stream --578de3b0e3c46.2334ba3 Content-Disposition: form-data; name="bar"; filename="bar.png" Content-Length: 71 Content-Type: image/png ?PNG ??? IHDR??? ??? ?????? ???? IDATxc???51?)?:??????IEND?B`? --578de3b0e3c46.2334ba3 Content-Type: text/plain Content-Disposition: form-data; name="baz" Content-Length: 6 string --578de3b0e3c46.2334ba3--
In the request above you see a set of HTTP headers and a body with two streams. The body starts and ends with a "boundary" and it is also this boundary that separates the streams. That boundary also needs to be specified in the Content-Type header.
Building a Multipart Stream
To build a multipart stream you may use the MultipartStreamBuilder. It is not coupled to any stream implementation so it needs a StreamFactory to create the streams.
$streamFactory = StreamFactoryDiscovery::find(); $builder = new MultipartStreamBuilder($streamFactory); $builder ->addResource('foo', $stream) ->addResource('bar', fopen($filePath, 'r'), ['filename' => 'bar.png']) ->addData('baz', ['headers' => ['Content-Type' => 'text/plain']]); $multipartStream = $builder->build(); $boundary = $builder->getBoundary(); $request = MessageFactoryDiscovery::find()->createRequest( 'POST', 'http://example.com', ['Content-Type' => 'multipart/form-data; boundary="'.$boundary.'"'], $multipartStream ); $response = HttpClientDiscovery::find()->sendRequest($request);
The second parameter of MultipartStreamBuilder::addResource() is the content of the stream. The supported input is the same as StreamFactory::createStream().