昨天的文章中,我們提到 roadrunner 可以跟 PSR-7 相容,至於什麼是 PSR-7 呢?
PSR-7 HTTP message interface,其中定義了一系列 HTTP 協定中可使用的 interface,目的是讓實現(implement)這些 interface 的 Class 都可以相互溝通。
PSR-7 一共定義了 7 個 interfaces(下述一併表現其繼承關係):
MessageInterface
RequestInterface
ServerRequestInterface
ResponseInterface
StreamInterface
UriInterface
UploadedFileInterface
MessageInterface
分為兩大類:RequestInterface
及 ResponseInterface
RequestInterface
表示 Client 發出的 HTTP RequestServerRequestInterface
表示由 Server 端收到的 HTTP RequestRequestInterface
只需要在乎 Target、Method、Uri;ServerRequestInterface
還需要重新析構一些超全域變數($_GET
, $_POST
, $_SERVER
, $_FILES
等)
表示由 Server 的 HTTP Response,其中比較重要的內容是 Status Code。
事實上,還可以獲取 Response Reason Phrase(例如 200 OK
的 OK
就是 Reason Phrase),但它並不是必須元素,所以可能為空。
用於描述 HTTP Stream 的介面,它是一個類似於 Day 19:自定義 Stream 中提到的 Stream Wrapper。
它用於讀取/寫入 HTTP Stream,例如用於讀取 Request,或為 Response 寫入一些額外資訊。
註:實現這個 interface 的 Class 是不能直接註冊為 Stream Wrapper 的(其實現的 methods 並不同)。
用於描述 Uri 的介面,主要是遵守 RFC 3986 的實現,讓設定/讀取 Uri 資訊時有個依據。
檔案上傳一直是很麻煩的議題,雖然 PHP 提供 $_FILES
這樣的超全域變數,但在某些情況下可能會失效
這個 Interface 的目的在於一致化各種不同的情況,並且能夠獲取上傳檔案中的相關資訊。
PSR-7 最大的優勢在於:只要實現了 PSR-7 的 Interface,就可以無痛直接介接到其它也有實現 PSR-7 的程式之中。
最明顯的例子應該就是 Roadrunner 了,只要實現了 PSR-7,Roadrunner 會處理掉其它所有的複雜事項。
當然 Swoole 也有 PSR-7 的 Bridge,例如 fastdlabs/http。
Slim Framework 中算是很早期就開始支援 PSR-7 的框架,下面展示一段程式
<?php
$app = Application::create();
$app->get('/home', function (Request $request, Response $response, array $args[]) {
$response->getBody()->write('Hello World');
return $response;
});
在 Request
與 Response
中都是實現了 PSR-7 的介面,也就是說在這個 Closure 中可以直接使用 PSR-7 介面所提供的一些方法。
Guzzle HTTP 應該是最早期支援 PSR-7 的 Client 端,這也讓它能夠輕易的 mock 一些 Request 及 Response,在 Unit Test 非常好用。
<?php
// 建立一些符合 PSR-7 的 MockHandler
$mock = new MockHandler([
new Response(200, ['X-Foo' => 'Bar']),
new Response(202, ['Content-Length' => 0]),
]);
// 為 Client 加入上面的 Mock Handler
$client = new Client(['handler' => HandlerStack::create($mock)]);
$client->request->get('GET', '/')->getStatusCode(); // 200
$client->request->get('GET', '/')->getStatusCode(); // 202
PSR-7 統合了 PHP 對於 HTTP Message 的處理方式,這也間接產生了 PSR-15: Middleware。
還有兩篇鐵人賽,應該是還來得及講到 PSR-15 的基本應用才對。