PSR 17 HTTP 工厂方法规范 「起草中」
本提案描述了创建符合 PSR-7 规范的 HTTP 对象的工厂方法的通用标准
PSR-7 规范中没有包含如何创建 HTTP 对象的建议,这导致在需要在与 PSR-7 的特定实现无关的组件中创建新的 HTTP 对象时会遇到困难
本提案描述的接口定义了实例化 PSR-7 规范中的对象的方法
本篇规范中的 必须,不得,需要,应,不应,应该,不应该,推荐,可能 和 可选 等词按照 RFC 2119 中的描述进行解释
1. 规范
HTTP 工厂方法是创建 PSR-7 定义的新 HTTP 对象的一种方法
HTTP 工厂 必须 为 PSR-7 包中提供的每种对象类型实现这些接口
2. 接口
下面的接口即可以在单个类中实现,也可以分别在多个类中实现
2.1 RequestFactoryInterface
可以创建客户端请求
<?php namespace Psr\Http\Message; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\UriInterface; interface RequestFactoryInterface { /** * 创建一个新的请求 * * @param string $method HTTP 请求方法 * @param UriInterface|string $uri 请求的目标 URL。 * 如果提供的是一个字符串,工厂方法 **必须** 基于它创建一个 UriInterface 实例 */ public function createRequest(string $method, $uri): RequestInterface; }
2.2 ResponseFactoryInterface
可以创建一个响应
<?php namespace Psr\Http\Message; use Psr\Http\Message\ResponseInterface; interface ResponseFactoryInterface { /** * 创建一个响应 * * @param int $code HTTP 状态码; 默认为 200 * @param string $reasonPhrase 响应状态原因短语, * 如果传递的是 null,实现类库可以使用 HTTP 规范中,与状态码相关的推荐值 */ public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface; }
2.3 ServerRequestFactoryInterface
创建一个服务请求
<?php namespace Psr\Http\Message; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\UriInterface; interface ServerRequestFactoryInterface { /** * 创建一个新的服务请求 * * 请注意: 新请求的服务器端参数与给定的值完全相同, * 并不会执行对给定值的解析/处理, * 特别是,不会尝试确定 HTTP 方法和 URI,所有所有数据都必须明确提供 * * @param string $method 与请求关联的 HTTP 方法 * @param UriInterface|string $uri 与请求关联的 URI。 * 如果该值是一个字符串,工厂必须基于它创建一个 UriInterface 实例 * @param array $serverParams 用于为生成的请求实例生成种子的 SAPI 参数数组 */ public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface; }
2.4 StreamFactoryInterface
为请求或这响应创建一个流
<?php namespace Psr\Http\Message; use Psr\Http\Message\StreamInterface; interface StreamFactoryInterface { /** * 从一个字符串创建一个新的流 * * 这个流 **必须** 应该使用临时资源来创建 * * * @param string $content 流中的内容就是字符串的内容 */ public function createStream(string $content = ''): StreamInterface; /** * 从一个已存在的文件中创建一个新的流 * * 文件必须使用给定的模式打开,这些模式可以是 `fopen` 函数支持的任意模式 * * `$filename` 参数 可以是 `fopen()` 函数支持的任意字符串 * * @param string $filename 可以作为流的文件名或 流 URI * @param string $mode 打开文件名/流的模式 */ public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface; /** * 从一个已经存在的资源中创建一个新的流 * * 这个流 **必须** 是可读的,但 **可以** 是可写的,也可不是 * * @param resource $resource 可以作为流的 PHP 资源 */ public function createStreamFromResource($resource): StreamInterface; }
实现这个接口的时候,从字符串资源中创建流时 必须 使用临时流
推荐的方式使用下面这种方式
<?php $resource = fopen('php://temp', 'r+');
2.5 UploadedFileFactoryInterface
创建一个流用于上传文件
<?php namespace Psr\Http\Message; use Psr\Http\Message\StreamInterface; use Psr\Http\Message\UploadedFileInterface; interface UploadedFileFactoryInterface { /** * 创建一个新的上传文件 * * 如果未提供大小,那么可以从数据流中自动侦测 * * @link http://php.net/manual/features.file-upload.post-method.php * @link http://php.net/manual/features.file-upload.errors.php * * @param StreamInterface $stream 代表上传文件内容的底层流 * @param int $size 字节为单位的文件大小 * @param int $error PHP 文件上传错误码 * @param string $clientFilename 客户端提供的文件名称 * @param string $clientMediaType 客户端提供的媒体类型 * * @throws \InvalidArgumentException 如果文件资源不可读,则抛出此异常 */ public function createUploadedFile( StreamInterface $stream, int $size = null, int $error = \UPLOAD_ERR_OK, string $clientFilename = null, string $clientMediaType = null ): UploadedFileInterface; }
这个接口扩展自 StreamFactoryInterface
StreamFactoryInterface
为方法 createUploadedFile()
提供了一个 $stream
参数
2.6 UriFactoryInterface
在客户端或者服务端创建 URL
<?php namespace Psr\Http\Message; use Psr\Http\Message\UriInterface; interface UriFactoryInterface { /** * 创建一个新的 URL * * @param string $uri 需要被解析的 URL * * @throws \InvalidArgumentException 如果传递 URL 不能被解析,那么抛出异常 */ public function createUri(string $uri = '') : UriInterface; }