用PSR-7发出回应

时间:2015-10-23 14:25:54

标签: php psr-7

我正在努力了解PSR-7是如何工作的,我卡住了!这是我的代码:

$app->get('/', function () {
    $stream = new Stream('php://memory', 'rw');
    $stream->write('Foo');
    $response = (new Response())
        ->withHeader('Content-Type', 'text/html')
        ->withBody($stream);
});

我的Response对象是build,但现在我想发送它... PSR-7如何发送响应?我需要序列化吗?我可能错过了一件事......

2 个答案:

答案 0 :(得分:4)

Psr-7只是为http消息建模。它没有发送响应的功能。您需要使用另一个使用PSR-7消息的库。您可以查看zend stratigility或类似内容

答案 1 :(得分:1)

就像完成一样,即使问题超过两年:

响应是服务器向客户端发送的HTTP消息,是客户端向服务器发出请求的结果。

客户端需要一个字符串作为消息,由以下内容组成:

  • a&#34; 状态行&#34; (格式为HTTP/<protocol-version> <status-code> <reason-phrase>);
  • 标题的列表(每个标题格式为&#34; <header-name>: <comma-separ.-header-values>&#34;);
  • 空行;
  • 邮件正文(字符串)。

它看起来像这样(见PSR-7):

HTTP/1.1 200 OK
Content-Type: text/html
vary: Accept-Encoding

This is the response body

为了发出响应,必须实际执行三个操作:

  1. 发送&#34;状态行&#34;到客户端(使用header() PHP函数)。
  2. 将标题列表发送到客户端( dito )。
  3. 输出邮件正文。
  4. 棘手的部分由第三个操作表示。实现ResponseInterface的类的实例包含流对象作为消息正文。此对象必须转换为字符串并打印。该任务可以轻松完成,因为该流是实现StreamInterface的类的实例,而后者又强制执行魔法方法__toString()的定义。

    因此,通过执行前两个步骤并将输出函数(echoprint_r等)应用于响应实例的getBody()方法的结果,发送过程已经完成了。

    <?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:对于大量数据,最好使用php://temp流而不是php://memoryHere是原因。