我们都知道标准的HTTP请求方法和状态码吧?还是我们?
我们肯定知道它们应该是整数还是字符串,和/或应该如何规范化字符串值,对吧?
我们的IDE可以完全自动完成它们,对吗?
哦,不是这样的?
前段时间,一些人提出了创建一个与PSR-7psr/http-message包相关的实用程序库的想法,但包含一些有用的位,例如HTTP请求方法和状态代码的常量。
六个月前,我们发布了它……但没有公开。我今天在编写一些使用该包的单元测试时想起了这个事实,并认为我终于把它写下来了。
这个包是fig/http-message-util,可以通过Composer和Packagist获得:
$ composer require fig/http-message-util
它提供了两个接口:
Fig\Http\Message\RequestMethodInterface
,包含HTTPrequest方法值的常量。Fig\Http\Message\StatusCodeInterface
,包含HTTP状态代码值的常量。
这些常量分别以METHOD_
和STATUS_
为前缀,并使用最初定义它们的各种IETF规范中提供的标准名称。
例如,我可以编写如下所示的中间件:
use Fig\Http\Message\RequestMethodInterface as RequestMethod; use Fig\Http\Message\StatusCodeInterface as StatusCode; use Interop\Http\ServerMiddleware\DelegateInterface; use Interop\Http\ServerMiddleware\MiddlewareInterface; use Psr\Http\Message\ServerRequestInterface; use Zend\Diactoros\EmptyResponse; class RequestMethodNegotiation implements MiddlewareInterface { private $alwaysAllowed = [ RequestMethod::METHOD_HEAD, RequestMethod::METHOD_OPTIONS, ]; private $map; public function __construct(array $map) { $this->map = $map; } public function process(ServerRequestInterface $request, DelegateInterface $delegate) { $path = $request->getUri()->getPath(); if (! isset($this->map[$path])) { return $delegate->process($request); } $method = $request->getMethod(); if (in_array($method, $this->alwaysAllowed, true)) { // Always allowed return $delegate->process($request); } if (in_array($method, $this->map[$path], true)) { // In map; proceed return $delegate->process($request); } // Not allowed! return new EmptyResponse(StatusCode::STATUS_METHOD_NOT_ALLOWED, [ 'Allow' => implode(',', $this->map[$path]); ]); } }
以上内容需要注意的是:
-
$alwaysAllowed
使用RequestMethodInterface
常量来提供始终允许的HTTP方法列表;它不使用容易出现拼写错误的字符串。 -
当遇到不允许的方法时,我们使用
StatusCodeInterface
常量来提供状态。这允许我们使用代码完成,但也表示代码的意图。整数值很棒,但除非您记住所有状态代码,否则通常很容易忘记它们的意思。
要注意的另一件事是,我将接口别名为较短的名称。我们要求接口在图中具有Interface
后缀,但在这种情况下,我并不特别关心常量在接口中定义;我只想吃掉它们。这是PHP支持别名的原因之一。
如果你还没有使用这个包,并且使用PSR-7中间件,我强烈建议检查这个包!