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 实现中列出了所有异常抛出情况。
我一直致力于 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 实现中列出了所有异常抛出情况。