你的 Slim 应用程序的路由和中间件被赋予一个 PSR-7 请求对象,代表你的网络服务器接收到的当前 HTTP 请求。请求对象实现PSR-7 ServerRequestInterface,您可以使用它检查和操作 HTTP 请求方法、标头和正文。
PSR-7 请求对象被注入到你的 Slim 应用程序路由中作为路由回调的第一个参数,如下所示:
PSR-7 请求对象作为可调用中间件的第一个参数注入到你的 Slim 应用中间件中 ,如下所示:
每个 HTTP 请求都有一个方法,通常是以下方法之一:
您可以使用适当命名的 Request 对象方法检查 HTTP 请求的方法getMethod()
。
$method = $request->getMethod();
可以伪造或覆盖HTTP 请求方法。例如,如果您需要使用仅支持或请求PUT
的传统 Web 浏览器来模拟请求,这将很有用。GET
POST
有两种方法可以覆盖 HTTP 请求方法。您可以在请求的正文中包含一个
METHOD
参数POST
。HTTP 请求必须使用
application/x-www-form-urlencoded
内容类型。
您还可以使用自定义 HTTP 请求标头覆盖 HTTP 请求方法
X-Http-Method-Override
。这适用于任何 HTTP 请求内容类型。
每个 HTTP 请求都有一个 URI,用于标识所请求的应用程序资源。HTTP 请求 URI 有几个部分:
http
或https
)example.com
)80
或443
)/users/1
)sort=created&dir=asc
)您可以使用其方法获取 PSR-7 请求对象的URI 对象getUri()
:
$uri = $request->getUri();
PSR-7 请求对象的 URI 本身是一个对象,它提供以下方法来检查 HTTP 请求的 URL 部分:
a=1&b=2
)您可以使用 将查询参数作为 Request 对象上的关联数组获取getQueryParams()
。
每个 HTTP 请求都有标头。这些是描述 HTTP 请求但在请求正文中不可见的元数据。Slim 的 PSR-7 Request 对象提供了多种方法来检查其标头。
您可以使用 PSR-7 请求对象的getHeaders()
方法将所有 HTTP 请求标头作为关联数组获取。生成的关联数组的键是标头名称,其值本身是其各自标头名称的字符串值的数字数组。
您可以使用 PSR-7 请求对象的方法获取单个标头的值getHeader($name)
。这将返回给定标头名称的值数组。请记住,一个 HTTP 标头可能有多个值!
您还可以使用 PSR-7 请求对象的getHeaderLine($name)
方法获取一个以逗号分隔的字符串,其中包含给定标头的所有值。与方法不同
getHeader($name)
,此方法返回逗号分隔的字符串。
您可以使用 PSR-7 请求对象的方法测试标头是否存在
hasHeader($name)
。
每个 HTTP 请求都有一个主体。如果您正在构建一个使用 JSON 或 XML 数据的 Slim 应用程序,您可以使用 PSR-7 Request 对象的
getParsedBody()
方法将 HTTP 请求主体解析为原生 PHP 格式。请注意,正文解析因 PSR-7 实现而异。
根据您安装的 PSR-7 实现,您可能需要实现中间件以解析传入的输入。以下是解析传入输入的示例JSON
:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
class JsonBodyParserMiddleware implements MiddlewareInterface
{
public function process(Request $request, RequestHandler $handler): Response
{
$contentType = $request->getHeaderLine('Content-Type');
if (strstr($contentType, 'application/json')) {
$contents = json_decode(file_get_contents('php://input'), true);
if (json_last_error() === JSON_ERROR_NONE) {
$request = $request->withParsedBody($contents);
}
}
return $handler->handle($request);
}
}
从技术上讲,PSR-7 请求对象将 HTTP 请求主体表示为Psr\Http\Message\StreamInterface
. StreamInterface
您可以使用 PSR-7 Request 对象的
方法获取 HTTP 请求主体实例getBody()
。getBody()
如果传入的 HTTP 请求大小未知或对于可用内存而言太大,则该方法更可取。
结果Psr\Http\Message\StreamInterface
实例提供了以下方法来读取和迭代其底层 PHP resource
。
文件上传$_FILES
可从 Request 对象的
getUploadedFiles()
方法获得。这将返回一个以元素名称为键的数组
input
。
数组中的每个对象$files
都是以下方法的实例
Psr\Http\Message\UploadedFileInterface
并支持以下方法:
请参阅说明书,了解如何使用 POST 表单上传文件。
Slim 的 PSR-7 请求实现提供了这些额外的专有方法来帮助您进一步检查 HTTP 请求。
您可以通过检查标头是否使用请求的方法来检测X-Requested-With
XHRXMLHttpRequest
请求getHeaderLine()
。
if ($request->getHeaderLine('X-Requested-With') === 'XMLHttpRequest') {
// Do something
}
您可以使用 Request 对象的getHeaderLine()
方法获取 HTTP 请求内容类型。
$contentType = $request->getHeaderLine('Content-Type');
您可以使用 Request 对象的方法获取 HTTP 请求内容长度getHeaderLine()
。
$length = $request->getHeaderLine('Content-Length');
要获取与传入请求环境相关的数据,您需要使用getServerParams()
.
例如,要获取单个服务器参数:
$params = $request->getServerParams();
$authorization = $params['HTTP_AUTHORIZATION'] ?? null;
如果请求方法是POST
并且Content-Type
是application/x-www-form-urlencoded
or ,您可以按如下方式multipart/form-data
检索所有参数:POST
// Get all POST parameters
$params = (array)$request->getParsedBody();
// Get a single POST parameter
$foo = $params['foo'];
有时在中间件中,您需要路由参数。
在此示例中,我们首先检查用户是否已登录,其次检查用户是否有权查看他们尝试查看的特定视频。
$app
->get('/course/{id}', Video::class . ':watch')
->add(PermissionMiddleware::class);
<?php
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Routing\RouteContext;
class PermissionMiddleware
{
public function __invoke(Request $request, RequestHandler $handler)
{
$routeContext = RouteContext::fromRequest($request);
$route = $routeContext->getRoute();
$courseId = $route->getArgument('id');
// do permission logic...
return $handler->handle($request);
}
}
要从路由中获取基本路径,只需执行以下操作:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use Slim\Routing\RouteContext;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
$app->get('/', function(Request $request, Response $response) {
$routeContext = RouteContext::fromRequest($request);
$basePath = $routeContext->getBasePath();
// ...
return $response;
});
使用 PSR-7 可以将对象/值注入请求对象以进行进一步处理。在您的应用程序中,中间件通常需要将信息传递给您的路由闭包,而这样做的方法是通过属性将其添加到请求对象。
例如,在您的请求对象上设置一个值。
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
$app->add(function (Request $request, RequestHandler $handler) {
// Add the session storage to your request as [READ-ONLY]
$request = $request->withAttribute('session', $_SESSION);
return $handler->handle($request);
});
例如,如何检索值。
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
$app->get('/test', function (Request $request, Response $response) {
// Get the session from the request
$session = $request->getAttribute('session');
$response->getBody()->write('Yay, ' . $session['name']);
return $response;
});
请求对象也有批量功能。$request->getAttributes()
和$request->withAttributes()