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
```
';