【问题标题】:filter_var function with IPv6 URLs带有 IPv6 URL 的 filter_var 函数
【发布时间】:2014-10-09 01:44:32
【问题描述】:

有什么方法可以验证 IPv6 URL?

http://[2001:630:181:35::83]/index.php 应该是一个有效的 URL

但是 PHP 的 filter_var 函数会返回 false

如何添加对 IPv6 地址的支持?

【问题讨论】:

  • @Marcin 这个不是有效的副本。
  • 使用filter_var(),您无法验证 IPv6 URL。这在文档中并不是很清楚。经过一番研究,我发现了问题:php docs 中声明FILTER_VALIDATE_URL 根据RFC2396 验证输入。在该 RFC 中向下滚动到 3.2.2. Server-based Naming Authority 时,它会声明以下 主机是网络主机的域名,或者它的 IPv4 地址是一组由“.”分隔的四个十进制数字组。 不支持文字 IPv6 地址。
  • 这意味着您要么需要在logical_filters.c 中更改php 本身的源代码,也可能在sanitizing_filters.c 中更改,但我想这不是一个选项。我建议使用自定义正则表达式。我猜它应该在某个地方...This mighe be a good start
  • 我的文章:Regular Expression URI Validation 在这里可能会有所帮助。它包括 IPv6 的正则表达式以及RFC-3986 中指定的所有其他 URI 组件。

标签: php regex ipv6


【解决方案1】:

我将 FILTER_VALIDATE_URL 和 FILTER_VALIDATE_IP 与 FILTER_FLAG_IPV6 结合使用了一种解决方法。 这是一个无正则表达式的解决方案:

function validate($url)
{
    # 1. We validate the url
    if (false === filter_var($url, FILTER_VALIDATE_URL)) {

        # 2. Consider the posibility of an IPV6 host
        $host = parse_url($url, PHP_URL_HOST);
        $ipv6 = trim($host, '[]'); // trim potential enclosing tags for IPV6

        # 3. Validate IPV6
        if (false === filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
            return false;
        } else {

            # 4. We have a valid IPV6, replace it with a generic host url for further validation purposes
            $newUrl = str_replace($host, 'www.someUrl.com', $url);

            # 5. We validate the new url
            if (false === filter_var($newUrl, FILTER_VALIDATE_URL)) {
                return false;
            }
        }
    }

    return true;
}

注意:如果 url 无效,parse_url() 并不总是失败,因此 你不能盲目更换主机,在验证之前,你可能会错过主机本身的一些错误。 所以...在更改主机后再次验证似乎是 IPV6 的正确方法。

【讨论】:

    猜你喜欢
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2019-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多