1. 程式人生 > >PHP規範PSR7(HTTP訊息介面)介紹(一)

PHP規範PSR7(HTTP訊息介面)介紹(一)

本文件描述了RFC 7230和RFC 7231中描述的用於表示HTTP訊息的公共介面,以及RFC 3986中描述的用於HTTP訊息的URI。

HTTP訊息是Web開發的基礎。 Web瀏覽器和HTTP客戶端(如cURL)建立傳送到Web伺服器的HTTP請求訊息,Web伺服器提供HTTP響應訊息。伺服器端程式碼接收HTTP請求訊息,並返回HTTP響應訊息。

HTTP訊息通常是從終端使用者消費者中抽象出來的,但作為開發人員,我們通常需要知道它們的結構以及如何訪問或操作它們以執行我們的任務,無論是否可能向HTTP API發出請求,或處理傳入的請求。

每條HTTP請求訊息都有一個特定的形式:

POST /path HTTP/1.1
Host: example.com

foo=bar&baz=bat

請求的第一行是“請求行”,並按順序包含HTTP請求方法,請求目標(通常是絕對URI或Web伺服器上的路徑)以及HTTP協議版本。接下來是一個或多個HTTP標頭,一個空行和訊息正文。

HTTP響應訊息具有類似的結構:

HTTP/1.1 200 OK
Content-Type: text/plain

This is the response body

 第一行是“狀態行”,並按順序包含HTTP協議版本,HTTP狀態程式碼和“原因短語”,即人類可讀的狀態程式碼描述。與請求訊息類似,然後是一個或多個HTTP標頭,空行和訊息正文。

本文件中描述的介面是圍繞HTTP訊息的抽象和構成它們的元素。

本文件中的關鍵詞“必須”,“必須”,“必需”,“應該”,“不應該”,“應該”,“不應該”,“推薦”,“可以”和“可選”按照RFC 2119中的描述進行解釋。

1 簡介

1.1 訊息

HTTP訊息是從客戶端到伺服器的請求或從伺服器到客戶端的響應。該規範分別定義了HTTP訊息Psr \ Http \ Message \ RequestInterface和Psr \ Http \ Message \ ResponseInterface的介面。

Psr \ Http \ Message \ RequestInterface和Psr \ Http \ Message \ ResponseInterface都擴充套件了Psr \ Http \ Message \ MessageInterface。雖然Psr \ Http \ Message \ MessageInterface可以直接實現,但實現者應該實現Psr \ Http \ Message \ RequestInterface和Psr \ Http \ Message \ ResponseInterface。

從這裡開始,當引用這些介面時,將省略名稱空間Psr \ Http \ Message。

1.2 HTTP頭部

不區分大小寫的標頭欄位名稱

HTTP訊息包括不區分大小寫的頭欄位名稱。通過名稱從實現MessageInterface的類中以不區分大小寫的方式檢索標頭。例如,檢索foo標頭將返回與檢索FoO標頭相同的結果。同樣,設定Foo標頭將覆蓋任何先前設定的foo標頭值。

$message = $message->withHeader('foo', 'bar');

echo $message->getHeaderLine('foo');
// Outputs: bar

echo $message->getHeaderLine('FOO');
// Outputs: bar

$message = $message->withHeader('fOO', 'baz');
echo $message->getHeaderLine('foo');
// Outputs: baz

儘管可以不區分大小寫地檢索標題,但是原始情況必須由實現保留,特別是在使用getHeaders()檢索時。

不符合要求的HTTP應用程式可能取決於某種情況,因此在建立請求或響應時,使用者能夠指示HTTP標頭的大小寫是有用的。

具有多個值的標頭

為了容納具有多個值的標頭,但仍然提供了將標頭作為字串使用的便利,可以從MessageInterface的例項中將標頭檢索為陣列或字串。使用getHeaderLine()方法將標頭值檢索為包含不區分大小寫標頭的所有標頭值的字串,其名稱與逗號連線。使用getHeader()按名稱檢索特定於不區分大小寫的標頭的所有標頭值的陣列。

$message = $message
    ->withHeader('foo', 'bar')
    ->withAddedHeader('foo', 'baz');

$header = $message->getHeaderLine('foo');
// $header contains: 'bar, baz'

$header = $message->getHeader('foo');
// ['bar', 'baz']

注意:並非所有標頭值都可以使用逗號(例如,Set-Cookie)連線。使用這樣的頭時,基於MessageInterface的類的使用者應該依賴於getHeader()方法來檢索這樣的多值頭。

主機頭

在請求中,Host頭通常映象URI的主機元件,以及建立TCP連線時使用的主機。但是,HTTP規範允許Host標頭與兩者中的每一個都不同。

在構造期間,如果沒有提供Host頭,則實現必須嘗試從提供的URI設定Host頭。

預設情況下,RequestInterface :: withUri()將使用與傳遞的UriInterface的主機元件匹配的Host頭替換返回的請求的Host頭。

您可以通過為第二個($ preserveHost)引數傳遞true來選擇保留Host頭的原始狀態。當此引數設定為true時,返回的請求將不會更新返回訊息的Host標頭 - 除非訊息不包含Host標頭。

此表說明了getHeaderLine('Host')將為withUri()返回的請求返回的內容,其中$ preserveHost引數設定為true,用於各種初始請求和URI。

REQUEST HOST HEADER1 REQUEST HOST COMPONENT2 URI HOST COMPONENT3 RESULT
’’ ’’ ’’ ’’
’’ foo.com ’’ foo.com
’’ foo.com bar.com foo.com
foo.com ’’ bar.com foo.com
foo.com bar.com baz.com foo.com
  • 操作前的主機頭值。
  • 操作前請求中組成的URI的主機元件。
  • 通過withUri()注入的URI的主機元件。