Reputation: 1006
I'm trying to understand how PSR-7 works and I get stuck! Here is my code:
$app->get('/', function () {
$stream = new Stream('php://memory', 'rw');
$stream->write('Foo');
$response = (new Response())
->withHeader('Content-Type', 'text/html')
->withBody($stream);
});
My Response object is build but now I want to send it... How PSR-7 send response? Do I need serialization? I probably missed one thing...
Upvotes: 6
Views: 4282
Reputation:
Just as a completion, even if the question is more than two years old:
A response is a HTTP message sent by a server to a client, as result of a request from the client to the server.
The client expects a string as message, composed of:
HTTP/<protocol-version> <status-code> <reason-phrase>
);<header-name>: <comma-separ.-header-values>
");And it looks like this (see PSR-7):
HTTP/1.1 200 OK
Content-Type: text/html
vary: Accept-Encoding
This is the response body
In order to emit a response, one must actually perform three operations:
The tricky part is represented by the third operation. An instance of a class implementing the ResponseInterface
contains a stream object as the message body. And this object must be converted to a string and printed. The task can be easily accomplished, because the stream is an instance of a class implementing StreamInterface
, which, in turn, enforces the definition of a magical method __toString().
So, by performing the first two steps and applying an output function (echo
, print_r
, etc) to the result of the getBody()
method of the response instance, the emitting process is complete.
<?php
if (headers_sent()) {
throw new RuntimeException('Headers were already sent. The response could not be emitted!');
}
// Step 1: Send the "status line".
$statusLine = sprintf('HTTP/%s %s %s'
, $response->getProtocolVersion()
, $response->getStatusCode()
, $response->getReasonPhrase()
);
header($statusLine, TRUE); /* The header replaces a previous similar header. */
// Step 2: Send the response headers from the headers list.
foreach ($response->getHeaders() as $name => $values) {
$responseHeader = sprintf('%s: %s'
, $name
, $response->getHeaderLine($name)
);
header($responseHeader, FALSE); /* The header doesn't replace a previous similar header. */
}
// Step 3: Output the message body.
echo $response->getBody();
exit();
P.S: For large amounts of data it's better to use the php://temp
stream instead of php://memory
. Here is the reason.
Upvotes: 9
Reputation: 9008
Psr-7 just models http messages. It does not have functionalities to send responses. You need to use another library that consumes PSR-7 messages. You could have a look at zend stratigility or something of the like
Upvotes: 6