FILTER_VALIDATE_URL的FILTER_FLAG_SCHEME_REQUIRED和FILTER_FLAG_HOST_REQUIRED标志的用途是什么?

时间:2017-07-21 14:18:56

标签: php validation url

我们可以将filter_vars()FILTER_VALIDATE_URLflags

一起使用
FILTER_FLAG_SCHEME_REQUIRED
FILTER_FLAG_HOST_REQUIRED
FILTER_FLAG_PATH_REQUIRED
FILTER_FLAG_QUERY_REQUIRED

FILTER_VALIDATE_URL根据RFC 2396将值验证为URL,并在内部使用parse_url()并要求方案(协议)和主机部分。

如果我想要检查路径和查询部分,我也可以像这样使用filter_vars:

filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED | FILTER_FLAG_QUERY_REQUIRED);

但是FILTER_FLAG_SCHEME_REQUIREDFILTER_FLAG_HOST_REQUIRED标志的用途是什么?似乎无论我们是否指定这些标志,无论如何都会检查主机部件。

例如,过滤有效的相对URL,如下所示:

filter_var('test1/2.html', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED);

返回false。

2 个答案:

答案 0 :(得分:4)

PHP 7.3.0

FILTER_FLAG_SCHEME_REQUIREDFILTER_FLAG_HOST_REQUIRED现已在PHP 7.3.0中弃用,因为它们在FILTER_VALIDATE_URL中使用了。

你是对的。默认情况下,这两个标志处于打开状态,并且无法禁用它们,尽管官方文档中有说明(见下文)。正如你在问题中所写,它们毫无用处。我认为这是一个错误。有一个bugreport与此相关。

From PHP docs

  

请注意,有效的URL可能未指定HTTP协议http://因此可能需要进一步验证以确定URL使用预期协议,例如ssh://或mailto:。

From RFC2396

  URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
  absoluteURI   = scheme ":" ( hier_part | opaque_part )
  relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ]

  hier_part     = ( net_path | abs_path ) [ "?" query ]
  opaque_part   = uric_no_slash *uric

  uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
                  "&" | "=" | "+" | "$" | ","

  net_path      = "//" authority [ abs_path ]
  abs_path      = "/"  path_segments
  rel_path      = rel_segment [ abs_path ]

  rel_segment   = 1*( unreserved | escaped |
                      ";" | "@" | "&" | "=" | "+" | "$" | "," )

  scheme        = alpha *( alpha | digit | "+" | "-" | "." )

  authority     = server | reg_name

  reg_name      = 1*( unreserved | escaped | "$" | "," |
                      ";" | ":" | "@" | "&" | "=" | "+" )

  server        = [ [ userinfo "@" ] hostport ]
  userinfo      = *( unreserved | escaped |
                     ";" | ":" | "&" | "=" | "+" | "$" | "," )

  hostport      = host [ ":" port ]
  host          = hostname | IPv4address
  hostname      = *( domainlabel "." ) toplabel [ "." ]
  domainlabel   = alphanum | alphanum *( alphanum | "-" ) alphanum
  toplabel      = alpha | alpha *( alphanum | "-" ) alphanum
  IPv4address   = 1*digit "." 1*digit "." 1*digit "." 1*digit
  port          = *digit

  path          = [ abs_path | opaque_part ]
  path_segments = segment *( "/" segment )
  segment       = *pchar *( ";" param )
  param         = *pchar
  pchar         = unreserved | escaped |
                  ":" | "@" | "&" | "=" | "+" | "$" | ","

  query         = *uric

  fragment      = *uric

  uric          = reserved | unreserved | escaped
  reserved      = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
                  "$" | ","
  unreserved    = alphanum | mark
  mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" |
                  "(" | ")"

  escaped       = "%" hex hex
  hex           = digit | "A" | "B" | "C" | "D" | "E" | "F" |
                          "a" | "b" | "c" | "d" | "e" | "f"

  alphanum      = alpha | digit
  alpha         = lowalpha | upalpha

  lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
             "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
             "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
  upalpha  = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
             "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
             "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
  digit    = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
             "8" | "9"

如您所见,有效的URL可能没有方案部分或主机名部分(如果它是相对的)。可能FILTER_FLAG_SCHEME_REQUIREDFILTER_FLAG_HOST_REQUIRED应该有助于通过设计检查它们的存在。但它永远不可能。

答案 1 :(得分:0)

标志FILTER_FLAG_SCHEME_REQUIREDFILTER_FLAG_HOST_REQUIRED自5.2.1以来没有任何影响,因为它们始终处于打开状态,无法禁用它们,并且它们实际上并未在任何地方使用在PHP源代码中。

https://bugs.php.net/bug.php?id=75442

关于常量的使用,文档刚刚被澄清,但是为了保持向后兼容性,它们不可能在下一个主要的PHP发布之前被删除[例如:PHP8]。

有一小组硬编码方案不需要主机名部分,[mailto:news:file:]但是如果要实施验证没有主机或方案部分的其他URL,您需要编写调用parse_url()并在其返回时操作的内容。

您可以在此处查看当前的网址验证来源:https://github.com/php/php-src/blob/master/ext/filter/logical_filters.c#L517-L574