PSR-7 UriInterface - 百分比编码的无效组件

PSR-7 UriInterface - Invalid Components with Percent Encoding

我一直致力于 PSR-7 UriInterface 的实现,有关实现何时应为某些组件抛出 InvalidArgumentException 的规范有点令人费解。

例如,UriInterface::withPath specifies throwing such an exception given an invalid path,但同一个文档块指出,"Users can provide both encoded and decoded path characters," 因为,"Implementations ensure the correct encoding."

/**
 * ...
 *
 * Users can provide both encoded and decoded path characters.
 * Implementations ensure the correct encoding as outlined in getPath().
 *
 * @param string $path The path to use with the new instance.
 * @return static A new instance with the specified path.
 * @throws \InvalidArgumentException for invalid paths.
 */

实现负责管理编码在整个规范的其余部分得到证实。

由于实施确保了正确的编码,因此实施的用户似乎可以将任意数量的其他无效字符传递给 withPath 之类的函数,然后该函数将被正确编码而不是触发异常。

我能想到的唯一可以保证 InvalidArgumentException 的情况是如果向 withPath 传递了一个非字符串(无论其价值如何,似乎是 Guzzle's interpretation of the specification)。

真正严格阅读 PHP's brief introduction of InvalidArgumentException 似乎可以避免这种 "strict typing" 的解释,但我不禁想知道 PHP-FIG 是否还有其他内容请记住,特别是考虑到 URI 语法的复杂性。

是否存在任何情况下,如果 UriInterface 方法(如 withPath)传递的是字符串,它应该抛出异常?

我知道,你的问题有点老了:-)

你的假设完全正确!

关于部分:

Users can provide both encoded and decoded path characters.
Implementations ensure the correct encoding as outlined in getPath().

这与 "invalid paths"(在 @throws 标签中描述)无关。它只是声明 - 正如您正确断言的那样,用户可以提供编码和解码的字符,这些字符应该是正确的 - 在 相应 的意义上 - 百分比编码。例如。一些未编码的字符将进行百分比编码,而另一些则不会。原则上,编码方案为:

Percent-encode all URI path characters, except:

 - the unreserved characters,
 - the reserved characters of the subset "gen-delims",
 - the reserved characters of the subset "sub-delims",
 - the already percent-encoded characters.

另一方面,在以下参数无效的情况下会抛出异常 - InvalidArgumentException

  • withScheme: 不是字符串,也不是允许列表的一部分 计划;
  • withHost: 不是字符串;
  • withPort: 不是数字(或整数?)并且不在 [1, 65535] 范围内;
  • withPath: 不是字符串;
  • withQuery: 不是字符串;
  • withFragment: 不是字符串;

最后,特殊处理接收作为(可选 NULL)构造函数参数传递的 URI 字符串 ($uri):

  • 未设置
  • 不是字符串
  • 为空

... 和 URI 部分数组,作为对 URI 字符串参数调用 parse_url 的结果(此处抛出 UnexpectedValueException):

$uriParts = parse_url($uri);

if ($uriParts === FALSE) {
    throw new \UnexpectedValueException('URI could not be parsed!');
}

请注意,我已经在 UriInterface 实现中列出了所有异常抛出情况。