SlimPHP開發指南五:請求

教科書般的PHP框架學習指南javascript

注:翻譯水平有限,若有錯誤,歡迎指正php

概述

Your Slim app’s routes and middleware are given a PSR 7 request object that represents the current HTTP request received by your web server. The request object implements the PSR 7 ServerRequestInterface with which you can inspect and manipulate the HTTP request method, headers, and body.html

Slim應用程序的路由和中間件被賦予一個PSR 7請求對象,該對象表示web服務器接收到的當前HTTP請求。請求對象實現PSR 7 ServerRequestInterface,您可使用該接口檢查和操做HTTP請求方法、頭和主體。前端

如何獲取請求對象

The PSR 7 request object is injected into your Slim application routes as the first argument to the route callback like this:java

PSR 7請求對象做爲路由回調的第一個參數被注入到slim應用程序路由中,以下所示:web

<?php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

$app = new \Slim\App;
$app->get('/foo', function (ServerRequestInterface $request, ResponseInterface $response) {
    // Use the PSR 7 $request object

    return $response;
});
$app->run();
複製代碼
Figure 1: Inject PSR 7 request into application route callback.
複製代碼

The Request Method

Every HTTP request has a method that is typically one of:json

每一個HTTP請求都有一個方法,一般是:數組

  • GET
  • POST
  • PUT
  • DELETE
  • HEAD
  • PATCH
  • OPTIONS

You can inspect the HTTP request’s method with the Request object method appropriately named getMethod().瀏覽器

您可使用request對象的getMethod()方法來檢查HTTP請求的方法。bash

$method = $request->getMethod();
複製代碼

Because this is a common task, Slim’s built-in PSR 7 implementation also provides these proprietary methods that return true or false.

由於這是一個常見的任務,Slim的內置PSR 7還提供了這些返回true或false的專有方法。

  • $request->isGet()
  • $request->isPost()
  • $request->isPut()
  • $request->isDelete()
  • $request->isHead()
  • $request->isPatch()
  • $request->isOptions()

It is possible to fake or override the HTTP request method. This is useful if, for example, you need to mimic a PUT request using a traditional web browser that only supports GET or POST requests.

能夠僞造或覆蓋HTTP請求方法。例如,若是您須要使用只支持GET或POST請求的傳統web瀏覽器來模擬PUT請求,這將很是有用。

There are two ways to override the HTTP request method. You can include a _METHOD parameter in a POST request’s body. The HTTP request must use the application/x-www-form-urlencoded content type.

有兩種方法覆蓋HTTP請求方法。能夠在POST請求的主體中包含_METHOD參數。HTTP請求必須使用application/x-www-form-urlencoded內容類型。

POST /path HTTP/1.1
Host: example.com
Content-type: application/x-www-form-urlencoded
Content-length: 22

data=value&_METHOD=PUT
複製代碼
Figure 3: Override HTTP method with _METHOD parameter.
複製代碼

You can also override the HTTP request method with a custom X-Http-Method-Override HTTP request header. This works with any HTTP request content type.

還可使用自定義的X-Http-Method-Override HTTP請求頭重寫HTTP請求方法。這適用於任何HTTP請求內容類型。

POST /path HTTP/1.1
Host: example.com
Content-type: application/json
Content-length: 16
X-Http-Method-Override: PUT

{"data":"value"}
複製代碼
Figure 4: Override HTTP method with X-Http-Method-Override header.
複製代碼

You can fetch the original (non-overridden) HTTP method with the PSR 7 Request object’s method named getOriginalMethod().

您可使用PSR 7請求對象的方法getOriginalMethod()獲取原始的(未重寫的)HTTP方法。

請求URI

Every HTTP request has a URI that identifies the requested application resource. The HTTP request URI has several parts:

每一個HTTP請求都有一個URI來標識所請求的應用程序資源。HTTP請求URI有幾個部分:

  • Scheme (e.g. http or https)
  • Host (e.g. example.com)
  • Port (e.g. 80 or 443)
  • Path (e.g. /users/1)
  • Query string (e.g. sort=created&dir=asc)

You can fetch the PSR 7 Request object’s URI object with its getUri() method:

您可使用其getUri()方法獲取PSR 7請求對象的URI對象:

$uri = $request->getUri();
複製代碼

The PSR 7 Request object’s URI is itself an object that provides the following methods to inspect the HTTP request’s URL parts:

PSR 7請求對象的URI自己就是一個對象,它提供如下方法來檢查HTTP請求的URL部分:

  • getScheme()
  • getAuthority()
  • getUserInfo()
  • getHost()
  • getPort()
  • getPath()
  • getBasePath()
  • getQuery() (returns the full query string, e.g. a=1&b=2)
  • getFragment()
  • getBaseUrl()

You can get the query parameters as an associative array on the Request object using getQueryParams().

能夠經過請求對象的getQueryParams()方法已關聯數組的形式獲得查詢參數。

You can also get a single query parameter value, with optional default value if the parameter is missing, using getQueryParam(key,default = null).

您還可使用getQueryParam($key, $default = null)查詢單個參數值,若是缺乏該參數,則使用可選的默認值。

Base Path: If your Slim application's front-controller lives in a physical subdirectory beneath your document root directory, you can fetch the HTTP request's physical base path (relative to the document root) with the Uri object's getBasePath() method. This will be an empty string if the Slim application is installed in the document root's top-most directory.

基本路徑: 若是Slim應用程序的前端控制器位於文檔根目錄下的物理子目錄中,則可使用Uri對象的getBasePath()方法獲取HTTP請求的物理根路徑(相對於文檔根目錄)。若是Slim應用程序安裝在文檔根目錄的頂部目錄中,則該字符串爲空。

請求頭

Every HTTP request has headers. These are metadata that describe the HTTP request but are not visible in the request’s body. Slim’s PSR 7 Request object provides several methods to inspect its headers.

每一個HTTP請求都有頭。這些元數據描述HTTP請求,但在請求主體中不可見。Slim的PSR 7請求對象提供了幾種方法來檢查其頭部。

獲得全部頭

You can fetch all HTTP request headers as an associative array with the PSR 7 Request object’s getHeaders() method. The resultant associative array’s keys are the header names and its values are themselves a numeric array of string values for their respective header name.

您可使用PSR 7請求對象的getheader()方法以關聯數組的形式獲取全部HTTP請求頭。由此產生的關聯數組的鍵是標題名,其值自己是各自標題名的字符串值的數字數組。

$headers = $request->getHeaders();
foreach ($headers as $name => $values) {
    echo $name . ": " . implode(", ", $values);
}
複製代碼
Figure 5: Fetch and iterate all HTTP request headers as an associative array.
複製代碼

得到一個頭信息

You can get a single header’s value(s) with the PSR 7 Request object’s getHeader($name) method. This returns an array of values for the given header name. Remember, a single HTTP header may have more than one value!

您可使用PSR 7請求對象的getHeader($name)方法得到單個報頭的值。這將返回給定頭名的值數組。記住,一個HTTP頭可能有多個值!

$headerValueArray = $request->getHeader('Accept');
複製代碼
Figure 6: Get values for a specific HTTP header.
複製代碼

You may also fetch a comma-separated string with all values for a given header with the PSR 7 Request object’s getHeaderLine(name) method. Unlike the getHeader(name) method, this method returns a comma-separated string.

您還可使用PSR 7請求對象的getHeaderLine(name)方法獲取一個以逗號分隔的字符串,其中包含給定頭部的全部值。與getHeader(name)方法不一樣,該方法返回一個逗號分隔的字符串。

$headerValueString = $request->getHeaderLine('Accept');
複製代碼
Figure 7: Get single header's values as comma-separated string.
複製代碼

探測報頭

You can test for the presence of a header with the PSR 7 Request object’s hasHeader($name) method.

您可使用PSR 7請求對象的hasHeader($name)方法測試報頭是否存在。

if ($request->hasHeader('Accept')) {
    // Do something
}
複製代碼
Figure 8: Detect presence of a specific HTTP request header.
複製代碼

請求主體

Every HTTP request has a body. If you are building a Slim application that consumes JSON or XML data, you can use the PSR 7 Request object’s getParsedBody() method to parse the HTTP request body into a native PHP format. Slim can parse JSON, XML, and URL-encoded data out of the box.

每一個HTTP請求都有一個主體。若是正在構建一個使用JSON或XML數據的Slim應用程序,可使用PSR 7請求對象的getParsedBody()方法將HTTP請求體解析爲原生PHP格式。Slim能夠當即解析JSON、XML和url編碼的數據。

$parsedBody = $request->getParsedBody();
複製代碼
Figure 9: Parse HTTP request body into native PHP format
複製代碼
  • JSON requests are converted into associative arrays with json_decode($input, true).

    JSON請求經過json_decode($input, true)轉換爲關聯數組。

  • XML requests are converted into a SimpleXMLElement with simplexml_load_string($input).

    XML請求經過simplexml_load_string($input)轉換爲SimpleXMLElement。

  • URL-encoded requests are converted into a PHP array with parse_str($input).

    url編碼的請求被轉換成一個帶有parse_str($input)的PHP數組。

For URL-encoded requests, you can also get a single parameter value, with optional default value if the parameter is missing, using getParsedBodyParam(key,default = null).

對於url編碼的請求,還可使用getParsedBodyParam(key,default = null)得到單個參數值,若是缺乏參數,則使用可選的默認值。

Technically speaking, Slim’s PSR 7 Request object represents the HTTP request body as an instance of \Psr\Http\Message\StreamInterface. You can get the HTTP request body StreamInterface instance with the PSR 7 Request object’s getBody() method. The getBody() method is preferable if the incoming HTTP request size is unknown or too large for available memory.

從技術上講,Slim的PSR 7請求對象將HTTP請求體表示爲\ PSR \ HTTP \Message\StreamInterface的一個實例。您可使用PSR 7請求對象的getBody()方法得到HTTP請求體流接口實例。若是傳入的HTTP請求大小未知或對於可用內存過大,則使用getBody()方法更好。

$body = $request->getBody();
複製代碼
Figure 10: Get HTTP request body
複製代碼

The resultant \Psr\Http\Message\StreamInterface instance provides the following methods to read and iterate its underlying PHP resource.

生成的\Psr\Http\Message\StreamInterface實例提供瞭如下方法來讀取和迭代它的底層PHP資源。

  • getSize()
  • tell()
  • eof()
  • isSeekable()
  • seek()
  • rewind()
  • isWritable()
  • write($string)
  • isReadable()
  • read($length)
  • getContents()
  • getMetadata($key = null)

從新解析body

When calling getParsedBody on the Request object multiple times, the body is only parsed once, even if the Request body is modified in the meantime. To ensure the body is reparsed, the Request object’s method reparseBody can be used.

當對請求對象屢次調用getParsedBody時,即便同時修改了請求主體,也只解析一次主體。爲了確保主體被從新解析,可使用請求對象的reparseBody方法。

上傳文件

The file uploads in $_FILES are available from the Request object’s getUploadedFiles() method. This returns an array keyed by the name of the element.

$_FILES中的文件上載能夠從請求對象的getUploadedFiles()方法得到。這將返回一個數組,其鍵值爲元素的名稱。

$files = $request->getUploadedFiles();
複製代碼
Figure 11: Get uploaded files
複製代碼

Each object in the $files array is a instance of \Psr\Http\Message\UploadedFileInterface and supports the following methods:

$files數組中的每一個對象都是\Psr\Http\Message\UploadedFileInterface的一個實例,而且支持如下方法:

  • getStream()
  • moveTo($targetPath)
  • getSize()
  • getError()
  • getClientFilename()
  • getClientMediaType()

See the cookbook on how to upload files using a POST form.

Request Helpers

Slim’s PSR 7 Request implementation provides these additional proprietary methods to help you further inspect the HTTP request.

Slim的PSR 7請求實現提供了這些額外的專有方法來幫助您進一步檢查HTTP請求。

檢測XHR請求

You can detect XHR requests with the Request object’s isXhr() method. This method detects the presence of the X-Requested-With HTTP request header and ensures its value is XMLHttpRequest.

您可使用請求對象的isXhr()方法檢測XHR請求。此方法檢測X-Request-With HTTP請求頭的存在,並確保其值爲XMLHttpRequest。

POST /path HTTP/1.1
Host: example.com
Content-type: application/x-www-form-urlencoded
Content-length: 7
X-Requested-With: XMLHttpRequest

foo=bar
複製代碼
Figure 13: Example XHR request.
複製代碼
if ($request->isXhr()) {
    // Do something
}
複製代碼

Content Type

You can fetch the HTTP request content type with the Request object’s getContentType() method. This returns the Content-Type header’s full value as provided by the HTTP client.

您可使用請求對象的getContentType()方法獲取HTTP請求內容類型。這將返回HTTP客戶機提供的Content-Type頭的完整值。

$contentType = $request->getContentType();
複製代碼

Media Type

You may not want the complete Content-Type header. What if, instead, you only want the media type? You can fetch the HTTP request media type with the Request object’s getMediaType() method.

您可能不須要完整的內容類型頭。若是您只須要媒體類型呢?您可使用請求對象的getMediaType()方法獲取HTTP請求媒體類型。

$mediaType = $request->getMediaType();
複製代碼

You can fetch the appended media type parameters as an associative array with the Request object’s getMediaTypeParams() method.

您可使用請求對象的getMediaTypeParams()方法以關聯數組的形式獲取附加的媒體類型參數。

$mediaParams = $request->getMediaTypeParams();
複製代碼

Character Set

One of the most common media type parameters is the HTTP request character set. The Request object provides a dedicated method to retrieve this media type parameter.

最多見的媒體類型參數之一是HTTP請求字符集。請求對象提供了一個專門的方法來檢索該媒體類型參數。

$charset = $request->getContentCharset();
複製代碼

Content Length

You can fetch the HTTP request content length with the Request object’s getContentLength() method.

您可使用請求對象的getContentLength()方法獲取HTTP請求內容長度。

$length = $request->getContentLength();
複製代碼

Request Parameter

To fetch single request parameter value, use methods: getParam(), getQueryParam(), getParsedBodyParam(), getCookieParam(), getServerParam(), counterparts of PSR-7’s plural form get*Params() methods.

要獲取單個請求參數值,可使用如下方法:getParam()、getQueryParam()、getParsedBodyParam()、getCookieParam()、getServerParam(),以及與PSR-7複數形式get*Params()方法對應的方法。

For example, to get a single Server Parameter:

$foo = $request->getServerParam('HTTP_NOT_EXIST', 'default_value_here');
複製代碼

Route Object

Sometimes in middleware you require the parameter of your route.

有時在中間件中須要路由的參數。

In this example we are checking first that the user is logged in and second that the user has permissions to view the particular video they are attempting to view.

在本例中,咱們首先檢查用戶是否已登陸,而後檢查用戶是否具備查看其試圖查看的特定視頻的權限。

$app->get('/course/{id}', Video::class.":watch")->add(Permission::class)->add(Auth::class);

    //.. In the Permission Class's Invoke /** @var $route \Slim\Route */ $route = $request->getAttribute('route'); $courseId = $route->getArgument('id'); 複製代碼

Media Type Parsers

Slim looks as the request’s media type and if it recognises it, will parse it into structured data available via $request->getParsedBody(). This is usually an array, but is an object for XML media types.

若是Slim識別出了媒體類型,就會將它解析爲可經過$request->getParsedBody()得到的結構化數據。這一般是一個數組,但它是XML媒體類型的對象。

The following media types are recognised and parsed:

  • application/x-www-form-urlencoded
  • application/json
  • application/xml & text/xml

If you want Slim to parse content from a different media type then you need to either parse the raw body yourself or register a new media parser. Media parsers are simply callables that accept an $input string and return a parsed object or array.

若是但願Slim解析來自不一樣媒體類型的內容,則須要本身解析原始體或註冊新媒體解析器。媒體解析器只是接受$input字符串並返回已解析對象或數組的可調用項。

Register a new media parser in an application or route middleware. Note that you must register the parser before you try to access the parsed body for the first time.

在應用程序或路由中間件中註冊新媒體解析器。注意,在第一次嘗試訪問被解析的主體以前,必須註冊解析器。

For example, to automatically parse JSON that is sent with a text/javascript content type, you register a media type parser in middleware like this:

例如,要自動解析文本/javascript內容類型發送的JSON,您須要在中間件中註冊一個媒體類型解析器,以下所示:

// Add the middleware
$app->add(function ($request, $response, $next) {
    // add media parser
    $request->registerMediaTypeParser(
        "text/javascript",
        function ($input) {
            return json_decode($input, true);
        }
    );

    return $next($request, $response);
});
複製代碼

Attributes

With PSR-7 it is possible to inject objects/values into the request object for further processing. In your applications middleware often need to pass along information to your route closure and the way to do is it is to add it to the request object via an attribute.

使用PSR-7,能夠將對象/值注入請求對象以進行進一步處理。在應用程序中,中間件一般須要將信息傳遞給路由閉包,方法是經過屬性將其添加到請求對象中。

Example, Setting a value on your request object.

$app->add(function ($request, $response, $next) {
    $request = $request->withAttribute('session', $_SESSION); //add the session storage to your request as [READ-ONLY]
    return $next($request, $response);
});
複製代碼

Example, how to retrieve the value.

$app->get('/test', function ($request, $response, $args) {
    $session = $request->getAttribute('session'); //get the session from the request

    return $response->write('Yay, ' . $session['name']);
});
複製代碼

The request object also has bulk functions as well. $request->getAttributes() and $request->withAttributes()

請求對象還具備批量函數。$request->getAttributes()和$request->withAttributes()

相關文章
相關標籤/搜索