PSR-7 HTTP 消息接口规范

最后更新于:2022-04-02 02:19:39

[TOC] ## 安装 ``` composer require psr/http-message ``` ### 接口
Psr\Http\Message\MessageInterface ``` getHeaders() as $name => $values) { * echo $name . ': ' . implode(', ', $values); * } * * // 迭代的循环二维数组 * foreach ($message->getHeaders() as $name => $values) { * foreach ($values as $value) { * header(sprintf('%s: %s', $name, $value), false); * } * } * * 虽然报头信息是没有大小写之分,但是使用 `getHeaders()` 会返回保留了原本 * 大小写形式的内容。 * * @return string[][] 返回一个两维数组,第一维数组的「键」 **必须** 为单条报头信息的 * 名称,对应的是由字串组成的数组,请注意,对应的「值」 **必须** 是数组形式的。 */ public function getHeaders(); /** * 检查是否报头信息中包含有此名称的值,不区分大小写 * * @param string $name 不区分大小写的报头信息名称 * @return bool 找到返回 true,未找到返回 false */ public function hasHeader($name); /** * 根据给定的名称,获取一条报头信息,不区分大小写,以数组形式返回 * * 此方法以数组形式返回对应名称的报头信息。 * * 如果没有对应的报头信息,**必须** 返回一个空数组。 * * @param string $name 不区分大小写的报头字段名称。 * @return string[] 返回报头信息中,对应名称的,由字符串组成的数组值,如果没有对应 * 的内容,**必须** 返回空数组。 */ public function getHeader($name); /** * 根据给定的名称,获取一条报头信息,不区分大小写,以逗号分隔的形式返回 * * 此方法返回所有对应的报头信息,并将其使用逗号分隔的方法拼接起来。 * * 注意:不是所有的报头信息都可使用逗号分隔的方法来拼接,对于那些报头信息,请使用 * `getHeader()` 方法来获取。 * * 如果没有对应的报头信息,此方法 **必须** 返回一个空字符串。 * * @param string $name 不区分大小写的报头字段名称。 * @return string 返回报头信息中,对应名称的,由逗号分隔组成的字串,如果没有对应 * 的内容,**必须** 返回空字符串。 */ public function getHeaderLine($name); /** * 返回替换指定报头信息「键/值」对的消息实例。 * * 虽然报头信息是不区分大小写的,但是此方法必须保留其传参时的大小写状态,并能够在 * 调用 `getHeaders()` 的时候被取出。 * * 此方法在实现的时候,**必须** 保留原有的不可修改的 HTTP 消息对象,然后返回 * 一个更新后带有传参进去报头信息的实例 * * @param string $name 不区分大小写的报头字段名称。 * @param string|string[] $value 报头信息或报头信息数组。 * @return self * @throws \InvalidArgumentException 无效的报头字段或报头信息时抛出 */ public function withHeader($name, $value); /** * 返回一个报头信息增量的 HTTP 消息实例。 * * 原有的报头信息会被保留,新的值会作为增量加上,如果报头信息不存在的话,字段会被加上。 * * 此方法在实现的时候,**必须** 保留原有的不可修改的 HTTP 消息对象,然后返回 * 一个新的修改过的 HTTP 消息实例。 * * @param string $name 不区分大小写的报头字段名称。 * @param string|string[] $value 报头信息或报头信息数组。 * @return self * @throws \InvalidArgumentException 报头字段名称非法时会被抛出。 * @throws \InvalidArgumentException 报头头信息的值非法的时候会被抛出。 */ public function withAddedHeader($name, $value); /** * 返回被移除掉指定报头信息的 HTTP 消息实例。 * * 报头信息字段在解析的时候,**必须** 保证是不区分大小写的。 * * 此方法在实现的时候,**必须** 保留原有的不可修改的 HTTP 消息对象,然后返回 * 一个新的修改过的 HTTP 消息实例。 * * @param string $name 不区分大小写的头部字段名称。 * @return self */ public function withoutHeader($name); /** * 获取 HTTP 消息的内容。 * * @return StreamInterface 以数据流的形式返回。 */ public function getBody(); /** * 返回指定内容的 HTTP 消息实例。 * * 内容 **必须** 是 `StreamInterface` 接口的实例。 * * 此方法在实现的时候,**必须** 保留原有的不可修改的 HTTP 消息对象,然后返回 * 一个新的修改过的 HTTP 消息实例。 * * @param StreamInterface $body 数据流形式的内容。 * @return self * @throws \InvalidArgumentException 当消息内容不正确的时候抛出。 */ public function withBody(StreamInterface $body); } ```

Psr\Http\Message\RequestInterface ```
Psr\Http\Message\ServerRequestInterface ``` getQuery()` 或服务器参数中的 `QUERY_STRING` 获取原始的查询字符串并自行解析。 * * @return array */ public function getQueryParams(); /** * 返回具体指定查询字符串参数的实例。 * * 这些值 **应该** 在传入请求的闭包中保持不变。它们 **可能** 在实例化的时候注入, * 例如来自 `$_GET` 或者其他一些值(例如 URI)中得到。如果是通过解析 URI 获取,则 * 数据结构必须与 `parse_str()` 返回的内容兼容,以便处理查询参数、嵌套的代码可以复用。 * * 设置查询字符串参数 **不得** 更改存储的 URI 和服务器参数中的值。 * * 此方法在实现的时候,**必须** 保留原有的不可修改的 HTTP 消息实例,然后返回 * 一个新的修改过的 HTTP 消息实例。 * * @param array $query 查询字符串参数数组,通常来源于 `$_GET`。 * @return self */ public function withQueryParams(array $query); /** * 获取规范化的上传文件数据。 * * 这个方法会规范化返回的上传文件元数据树结构,每个叶子结点都是 `Psr\Http\Message\UploadedFileInterface` 实例。 * * 这些值 **可能** 在实例化的时候从 `$_FILES` 或消息体中获取,或者通过 `withUploadedFiles()` 获取。 * * @return array `UploadedFileInterface` 的实例数组;如果没有数据则必须返回一个空数组。 */ public function getUploadedFiles(); /** * 返回使用指定的上传文件数据的新实例。 * * 此方法在实现的时候,**必须** 保留原有的不可修改的 HTTP 消息实例,然后返回 * 一个新的修改过的 HTTP 消息实例。 * * @param array `UploadedFileInterface` 实例的树结构,类似于 `getUploadedFiles()` 的返回值。 * @return self * @throws \InvalidArgumentException 如果提供无效的结构时抛出。 */ public function withUploadedFiles(array $uploadedFiles); /** * 获取请求消息体中的参数。 * * 如果请求的 Content-Type 是 application/x-www-form-urlencoded 或 multipart/form-data 且请求方法是 POST, * 则此方法 **必须** 返回 $_POST 的内容。 * * 如果是其他情况,此方法可能返回反序列化请求正文内容的任何结果;当解析返回返回的结构化内容时,潜在的类型 **必须** * 只能是数组或 `object` 类型。`null` 表示没有消息体内容。 * * @return null|array|object 如果存在则返回反序列化消息体参数。一般是一个数组或 `object`。 */ public function getParsedBody(); /** * 返回具有指定消息体参数的实例。 * * **可能** 在实例化时注入。 * * 如果请求的 Content-Type 是 application/x-www-form-urlencoded 或 multipart/form-data 且请求方法是 POST, * 则方法的参数只能是 $_POST。 * * 数据不一定要来自 $_POST,但是 **必须** 是反序列化请求正文内容的结果。由于需要反序列化/解析返回的结构化数据, * 所以这个方法只接受数组、 `object` 类型和 `null`(如果没有可用的数据解析)。 * * 例如,如果确定请求数据是一个 JSON,可以使用此方法创建具有反序列化参数的请求实例。 * * 此方法在实现的时候,**必须** 保留原有的不可修改的 HTTP 消息实例,然后返回 * 一个新的修改过的 HTTP 消息实例。 * * @param null|array|object $data 反序列化的消息体数据,通常是数组或 `object`。 * @return self * @throws \InvalidArgumentException 如果提供的数据类型不支持。 */ public function withParsedBody($data); /** * 获取从请求派生的属性。 * * 请求「attributes」可用于从请求导出的任意参数:比如路径匹配操作的结果;解密 Cookie 的结果; * 反序列化非表单编码的消息体的结果;属性将是应用程序与请求特定的,并且可以是可变的。 * * @return mixed[] 从请求派生的属性。 */ public function getAttributes(); /** * 获取单个派生的请求属性。 * * 获取 getAttributes() 中声明的某一个属性,如果不存在则返回提供的默认值。 * * 这个方法不需要 hasAttribute 方法,因为允许在找不到指定属性的时候返回默认值。 * * @see getAttributes() * @param string $name 属性名称。 * @param mixed $default 如果属性不存在时返回的默认值。 * @return mixed */ public function getAttribute($name, $default = null); /** * 返回具有指定派生属性的实例。 * * 此方法允许设置 getAttributes() 中声明的单个派生的请求属性。 * * 此方法在实现的时候,**必须** 保留原有的不可修改的 HTTP 消息实例,然后返回 * 一个新的修改过的 HTTP 消息实例。 * * @see getAttributes() * @param string $name 属性名。 * @param mixed $value 属性值。 * @return self */ public function withAttribute($name, $value); /** * 返回移除指定属性的实例。 * * 此方法允许移除 getAttributes() 中声明的单个派生的请求属性。 * * 此方法在实现的时候,**必须** 保留原有的不可修改的 HTTP 消息实例,然后返回 * 一个新的修改过的 HTTP 消息实例。 * * @see getAttributes() * @param string $name 属性名。 * @return self */ public function withoutAttribute($name); } ```

Psr\Http\Message\ResponseInterface ```
Psr\Http\Message\StreamInterface ```
Psr\Http\Message\UriInterface ``` * [user-info@]host[:port] * * * 如果端口部分没有设置,或者端口不是标准端口,**不应该** 包含在返回值内。 * * @see https://tools.ietf.org/html/rfc3986#section-3.2 * @return string URI 认证信息,格式为:「[user-info@]host[:port]」。 */ public function getAuthority(); /** * 从 URI 中获取用户信息。 * * 如果不存在用户信息,此方法 **必须** 返回一个空字符串。 * * 如果 URI 中存在用户,则返回该值;此外,如果密码也存在,它将附加到用户值,用冒号(「:」)分隔。 * * 用户信息后面跟着的 "@" 字符,不是用户信息里面的一部分,**不得** 在返回值里出现。 * * @return string URI 的用户信息,格式:"username[:password]" */ public function getUserInfo(); /** * 从 URI 中获取 HOST 信息。 * * 如果 URI 中没有此值,**必须** 返回空字符串。 * * 根据 RFC 3986 规范 3.2.2 章节,返回的数据 **必须** 是小写字母。 * * @see http://tools.ietf.org/html/rfc3986#section-3.2.2 * @return string URI 中的 HOST 信息。 */ public function getHost(); /** * 从 URI 中获取端口信息。 * * 如果端口信息是与当前 Scheme 的标准端口不匹配的话,就使用整数值的格式返回,如果是一 * 样的话,**应该** 返回 `null` 值。 * * 如果不存在端口和 Scheme 信息,**必须** 返回 `null` 值。 * * 如果不存在端口数据,但是存在 Scheme 的话,**可能** 返回 Scheme 对应的 * 标准端口,但是 **应该** 返回 `null`。 * * @return null|int URI 中的端口信息。 */ public function getPort(); /** * 从 URI 中获取路径信息。 * * 路径可以是空的,或者是绝对的(以斜线「/」开头),或者相对路径(不以斜线开头)。 * 实现 **必须** 支持所有三种语法。 * * 根据 RFC 7230 第 2.7.3 节,通常空路径「」和绝对路径「/」被认为是相同的。 * 但是这个方法 **不得** 自动进行这种规范化,因为在具有修剪的基本路径的上下文中, * 例如前端控制器中,这种差异将变得显著。用户的任务就是可以将「」和「/」都处理好。 * * 返回的值 **必须** 是百分号编码,但 **不得** 对任何字符进行双重编码。 * 要确定要编码的字符,请参阅 RFC 3986 第 2 节和第 3.3 节。 * * 例如,如果值包含斜线(「/」)而不是路径段之间的分隔符,则该值必须以编码形式(例如「%2F」) * 传递给实例。 * * @see https://tools.ietf.org/html/rfc3986#section-2 * @see https://tools.ietf.org/html/rfc3986#section-3.3 * @return string URI 路径信息。 */ public function getPath(); /** * 获取 URI 中的查询字符串。 * * 如果不存在查询字符串,则此方法必须返回空字符串。 * * 前导的「?」字符不是查询字符串的一部分,**不得** 添加在返回值中。 * * 返回的值 **必须** 是百分号编码,但 **不得** 对任何字符进行双重编码。 * 要确定要编码的字符,请参阅 RFC 3986 第 2 节和第 3.4 节。 * * 例如,如果查询字符串的键值对中的值包含不做为值之间分隔符的(「&」),则该值必须 * 以编码形式传递(例如「%26」)到实例。 * * @see https://tools.ietf.org/html/rfc3986#section-2 * @see https://tools.ietf.org/html/rfc3986#section-3.4 * @return string URI 中的查询字符串 */ public function getQuery(); /** * 获取 URI 中的片段(Fragment)信息。 * * 如果没有片段信息,此方法 **必须** 返回空字符串。 * * 前导的「#」字符不是片段的一部分,**不得** 添加在返回值中。 * * 返回的值 **必须** 是百分号编码,但 **不得** 对任何字符进行双重编码。 * 要确定要编码的字符,请参阅 RFC 3986 第 2 节和第 3.5 节。 * * @see https://tools.ietf.org/html/rfc3986#section-2 * @see https://tools.ietf.org/html/rfc3986#section-3.5 * @return string URI 中的片段信息。 */ public function getFragment(); /** * 返回具有指定 Scheme 的实例。 * * 此方法 **必须** 保留当前实例的状态,并返回包含指定 Scheme 的实例。 * * 实现 **必须** 支持大小写不敏感的「http」和「https」的 Scheme,并且在 * 需要的时候 **可能** 支持其他的 Scheme。 * * 空的 Scheme 相当于删除 Scheme。 * * @param string $scheme 给新实例使用的 Scheme。 * @return self 具有指定 Scheme 的新实例。 * @throws \InvalidArgumentException 使用无效的 Scheme 时抛出。 * @throws \InvalidArgumentException 使用不支持的 Scheme 时抛出。 */ public function withScheme($scheme); /** * 返回具有指定用户信息的实例。 * * 此方法 **必须** 保留当前实例的状态,并返回包含指定用户信息的实例。 * * 密码是可选的,但用户信息 **必须** 包括用户;用户信息的空字符串相当于删除用户信息。 * * @param string $user 用于认证的用户名。 * @param null|string $password 密码。 * @return self 具有指定用户信息的新实例。 */ public function withUserInfo($user, $password = null); /** * 返回具有指定 HOST 信息的实例。 * * 此方法 **必须** 保留当前实例的状态,并返回包含指定 HOST 信息的实例。 * * 空的 HOST 信息等同于删除 HOST 信息。 * * @param string $host 用于新实例的 HOST 信息。 * @return self 具有指定 HOST 信息的实例。 * @throws \InvalidArgumentException 使用无效的 HOST 信息时抛出。 */ public function withHost($host); /** * 返回具有指定端口的实例。 * * 此方法 **必须** 保留当前实例的状态,并返回包含指定端口的实例。 * * 实现 **必须** 为已建立的 TCP 和 UDP 端口范围之外的端口引发异常。 * * 为端口提供的空值等同于删除端口信息。 * * @param null|int $port 用于新实例的端口;`null` 值将删除端口信息。 * @return self 具有指定端口的实例。 * @throws \InvalidArgumentException 使用无效端口时抛出异常。 */ public function withPort($port); /** * 返回具有指定路径的实例。 * * 此方法 **必须** 保留当前实例的状态,并返回包含指定路径的实例。 * * 路径可以是空的、绝对的(以斜线开头)或者相对路径(不以斜线开头),实现必须支持这三种语法。 * * 如果 HTTP 路径旨在与 HOST 相对而不是路径相对,,那么它必须以斜线开头。 * 假设 HTTP 路径不以斜线开头,对应该程序或开发人员来说,相对于一些已知的路径。 * * 用户可以提供编码和解码的路径字符,要确保实现了 `getPath()` 中描述的正确编码。 * * @param string $path 用于新实例的路径。 * @return self 具有指定路径的实例。 * @throws \InvalidArgumentException 使用无效的路径时抛出。 */ public function withPath($path); /** * 返回具有指定查询字符串的实例。 * * 此方法 **必须** 保留当前实例的状态,并返回包含查询字符串的实例。 * * 用户可以提供编码和解码的查询字符串,要确保实现了 `getQuery()` 中描述的正确编码。 * * 空查询字符串值等同于删除查询字符串。 * * @param string $query 用于新实例的查询字符串。 * @return self 具有指定查询字符串的实例。 * @throws \InvalidArgumentException 使用无效的查询字符串时抛出。 */ public function withQuery($query); /** * 返回具有指定 URI 片段(Fragment)的实例。 * * 此方法 **必须** 保留当前实例的状态,并返回包含片段的实例。 * * 用户可以提供编码和解码的片段,要确保实现了 `getFragment()` 中描述的正确编码。 * * 空片段值等同于删除片段。 * * @param string $fragment 用于新实例的片段。 * @return self 具有指定 URI 片段的实例。 */ public function withFragment($fragment); /** * 返回字符串表示形式的 URI。 * * 根据 RFC 3986 第 4.1 节,结果字符串是完整的 URI 还是相对引用,取决于 URI 有哪些组件。 * 该方法使用适当的分隔符连接 URI 的各个组件: * * - 如果存在 Scheme 则 **必须** 以「:」为后缀。 * - 如果存在认证信息,则必须以「//」作为前缀。 * - 路径可以在没有分隔符的情况下连接。但是有两种情况需要调整路径以使 URI 引用有效,因为 PHP * 不允许在 `__toString()` 中引发异常: * - 如果路径是相对的并且有认证信息,则路径 **必须** 以「/」为前缀。 * - 如果路径以多个「/」开头并且没有认证信息,则起始斜线 **必须** 为一个。 * - 如果存在查询字符串,则 **必须** 以「?」作为前缀。 * - 如果存在片段(Fragment),则 **必须** 以「#」作为前缀。 * * @see http://tools.ietf.org/html/rfc3986#section-4.1 * @return string */ public function __toString(); } ```

Psr\Http\Message\UploadedFileInterface ```
';