The Request

最后更新于:2022-04-01 04:24:26

# Request [TOC=2,3] 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](http://www.php-fig.org/psr/psr-7/#3-2-1-psr-http-message-serverrequestinterface) with which you can inspect and manipulate the HTTP request method, headers, and body. ## How to get the Request object The PSR 7 request object is injected into your Slim application routes as the first argument to the route callback like this: ~~~ <?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 PSR 7 request object is injected into your Slim application *middleware* as the first argument of the middleware callable like this: ~~~ <?php use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; $app = new \Slim\App; $app->add(function (ServerRequestInterface $request, ResponseInterface $response, callable $next) { // Use the PSR 7 $request object return $next($request, $response); }); // Define app routes... $app->run(); ~~~ Figure 2: Inject PSR 7 request into application middleware. ## The Request Method Every HTTP request has a method that is typically one of: * GET * POST * PUT * DELETE * HEAD * PATCH * OPTIONS You can inspect the HTTP request’s method with the Request object method appropriately named `getMethod()`. ~~~ $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`. * `$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. 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. ~~~ 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. ~~~ 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()`. ## The Request URI Every HTTP request has a URI that identifies the requested application resource. The HTTP request URI has several parts: * 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 with its `getUri()` method: ~~~ $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: * `getScheme()` * `getHost()` * `getPort()` * `getPath()` * `getBasePath()` * `getQuery()` (returns string) * `getQueryParams()` (returns associative array) 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. ## The Request Headers 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. ### Get All Headers 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. ~~~ $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. ### Get One Header 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!* ~~~ $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. ~~~ $headerValueString = $request->getHeaderLine('Accept'); ~~~ Figure 7: Get single header's values as comma-separated string. ### Detect Header You can test for the presence of a header with the PSR 7 Request object’s `hasHeader($name)`method. ~~~ if ($request->hasHeader('Accept')) { // Do something } ~~~ Figure 8: Detect presence of a specific HTTP request header. ## The Request Body 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. ~~~ $parsedBody = $request->getParsedBody(); ~~~ Figure 9: Parse HTTP request body into native PHP format * JSON requests are converted into a PHP object with `json_decode($input)`. * XML requests are converted into a `SimpleXMLElement` with`simplexml_load_string($input)`. * URL-encoded requests are converted into a PHP array with `parse_str($input)`. 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. ~~~ $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`. * `getSize()` * `tell()` * `eof()` * `isSeekable()` * `seek()` * `rewind()` * `isWritable()` * `write($string)` * `isReadable()` * `read($length)` * `getContents()` * `getMetadata($key = null)` ## Request Helpers Slim’s PSR 7 Request implementation provides these additional proprietary methods to help you further inspect the HTTP request. ### Detect XHR requests 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`. ~~~ 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 11: 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. ~~~ $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. ~~~ $mediaType = $request->getMediaType(); ~~~ You can fetch the appended media type parameters as an associative array with the Request object’s `getMediaTypeParams()` method. ~~~ $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. ~~~ $charset = $request->getContentCharset(); ~~~ ### Content Length You can fetch the HTTP request content length with the Request object’s `getContentLength()`method. ~~~ $length = $request->getContentLength(); ~~~ ### IP Address You can fetch the HTTP request’s source IP address with the Request object’s `getIp()`method. This method respects the `X-Forwarded-For` header, if present. ~~~ $ip = $request->getIp(); ~~~
';