我们都知道标准的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中间件,我强烈建议检查这个包!
