验证过滤器

验证过滤器的列表
ID 名称 选项 标志 描述
FILTER_VALIDATE_BOOLEAN, FILTER_VALIDATE_BOOL "boolean" 默认 FILTER_NULL_ON_FAILURE

对于 "1"、"true"、"on" 和 "yes" 返回 true。否则返回 false

如果设置了 FILTER_NULL_ON_FAILURE,则仅对于 "0"、"false"、"off"、"no" 和 "" 返回 false,而对于所有非布尔值返回 null

字符串值在比较之前使用 trim() 进行修剪。

FILTER_VALIDATE_DOMAIN "validate_domain" 默认 FILTER_FLAG_HOSTNAME, FILTER_NULL_ON_FAILURE

验证域名标签长度是否有效。

根据 RFC 1034、RFC 1035、RFC 952、RFC 1123、RFC 2732、RFC 2181 和 RFC 1123 验证域名。可选标志 FILTER_FLAG_HOSTNAME 添加了专门验证主机名的功能(它们必须以字母数字字符开头,并且只能包含字母数字字符或连字符)。

FILTER_VALIDATE_EMAIL "validate_email" 默认 FILTER_FLAG_EMAIL_UNICODE, FILTER_NULL_ON_FAILURE

验证该值是否为有效的电子邮件地址。

通常,这会根据 » RFC 822 中的 addr-spec 语法验证电子邮件地址,但有以下例外:不支持注释、空格折叠和无点域名。

FILTER_VALIDATE_FLOAT "float" default, decimal, min_range, max_range FILTER_FLAG_ALLOW_THOUSAND, FILTER_NULL_ON_FAILURE

将值验证为浮点数,可选地来自指定范围,并在成功时转换为浮点数。

字符串值在比较之前使用 trim() 进行修剪。

FILTER_VALIDATE_INT "int" default, min_range, max_range FILTER_FLAG_ALLOW_OCTAL, FILTER_FLAG_ALLOW_HEX, FILTER_NULL_ON_FAILURE

将值验证为整数,可选地来自指定范围,并在成功时转换为整数。

字符串值在比较之前使用 trim() 进行修剪。

FILTER_VALIDATE_IP "validate_ip" 默认 FILTER_FLAG_IPV4, FILTER_FLAG_IPV6, FILTER_FLAG_NO_PRIV_RANGE, FILTER_FLAG_NO_RES_RANGE, FILTER_FLAG_GLOBAL_RANGE, FILTER_NULL_ON_FAILURE 将值验证为 IP 地址,可选地仅为 IPv4 或 IPv6,或者不来自私有或保留范围。
FILTER_VALIDATE_MAC "validate_mac_address" 默认 FILTER_NULL_ON_FAILURE 将值验证为 MAC 地址。
FILTER_VALIDATE_REGEXP "validate_regexp" default, regexp FILTER_NULL_ON_FAILURE 根据 regexp(一个 与 Perl 兼容 的正则表达式)验证值。
FILTER_VALIDATE_URL "validate_url" 默认 FILTER_FLAG_SCHEME_REQUIRED, FILTER_FLAG_HOST_REQUIRED, FILTER_FLAG_PATH_REQUIRED, FILTER_FLAG_QUERY_REQUIRED, FILTER_NULL_ON_FAILURE 将值验证为 URL(根据 » http://www.faqs.org/rfcs/rfc2396),可选地包含必需的组件。注意,有效 URL 可能不会指定 HTTP 协议 http://,因此可能需要进一步验证以确定 URL 使用的是预期的协议,例如 ssh://mailto:。请注意,该函数只会找到 ASCII URL 为有效 URL;国际化域名(包含非 ASCII 字符)将无法验证。

注意:

default 设置为选项时,如果值未验证,则使用 default 的值。

变更日志

版本 描述
8.0.0 FILTER_FLAG_SCHEME_REQUIREDFILTER_FLAG_HOST_REQUIRED 标志已从 FILTER_VALIDATE_URL 过滤器中移除。 schemehost 始终是(并且一直是)必需的。
8.0.0 添加了 FILTER_VALIDATE_BOOL 作为 FILTER_VALIDATE_BOOLEAN 的别名。建议使用 FILTER_VALIDATE_BOOL
7.4.0 FILTER_VALIDATE_FLOAT 添加了 min_rangemax_range 选项。
7.0.0 添加了 FILTER_FLAG_HOSTNAMEFILTER_VALIDATE_DOMAIN

添加注释

用户贡献的注释 26 个注释

boy at relaxnow dot nl
11 年前
FILTER_VALIDATE_URL 不适用于 URN,以下是一些根据 RFC3986 验证的有效 URI,以及它们是否被 FILTER_VALIDATE_URL 接受

[通过] ftp://ftp.is.co.za.example.org/rfc/rfc1808.txt
[通过] gopher://spinaltap.micro.umn.example.edu/00/Weather/California/Los%20Angeles
[通过] http://www.math.uio.no.example.net/faq/compression-faq/part1.html
[通过] mailto:[email protected]
[通过] news:comp.infosystems.www.servers.unix
[通过] telnet://melvyl.ucop.example.edu/
[通过] http://www.ietf.org/rfc/rfc2396.txt
[通过] ldap://[2001:db8::7]/c=GB?objectClass?one
[通过] mailto:[email protected]
[通过] news:comp.infosystems.www.servers.unix
[失败] tel:+1-816-555-1212
[通过] telnet://192.0.2.16:80/
[失败] urn:oasis:names:specification:docbook:dtd:xml:4.1.2
bee kay two at em ee dot com
12 年前
值得注意的是,缺少验证文本输入是否可打印的方法,
可打印的多行,
或可打印且安全(无标签)

FILTER_VALIDATE_TEXT,它验证没有特殊字符
可能使用 FILTER_FLAG_ALLOW_NEWLINE
以及 FILTER_FLAG_NOTAG 来禁止标签开头
MR Yekta
4 年前
自 php 7.4 起
您可以使用这三个漂亮的条件来验证小于、大于或在范围内

<?php
/**
* 小于或等于
*/
$x = 50;
if (
filter_var($x, FILTER_VALIDATE_FLOAT, ["options" => ["max_range" => 100]]) !== false) {
echo
"结果:$x 小于或等于 100";
} else {
echo
"结果:$x 不小于或等于 100";
}
?>
结果:50 小于或等于 100

<?php
/**
* 大于等于
*/
$x = 50;
if (
filter_var($x, FILTER_VALIDATE_FLOAT, ["options" => ["min_range" => 100]]) !== false) {
echo
"result : $x 大于或等于 100";
} else {
echo
"result : $x 不大于或等于 100";
}
?>
result : 50 不大于或等于 100

<?php
/**
* 小于等于 && 大于等于
*/
$x = 50;
if (
filter_var($x, FILTER_VALIDATE_FLOAT, ["options" => ["min_range" => 0 , "max_range"=> 100]]) !== false) {
echo
"result : $x 在 0 到 100 的范围内";
} else {
echo
"result : $x 不在 0 到 100 的范围内";
}
?>
result : 50 在 0 到 100 的范围内
bryanwayb at gmail dot com
9 年前
值得记住的是,使用 filter_var 主要用于在进行布尔逻辑比较时过滤输入值。例如

$value = "12";
if(filter_var($value, FILTER_VALIDATE_INT))
{
// 验证为整数
}

以上代码按预期工作,除了当 $value = "0" 时。在这种情况下,filter_var 返回 0,即在用作布尔值时为 false。

为了得到正确的结果,请进行零检查。

$value = " 0 ";
$filtered = filter_var($value, FILTER_VALIDATE_INT);
if($filtered || $filtered === 0)
{
// 验证为整数
}
Clifton
13 年前
FILTER_VALIDATE_EMAIL 并不允许验证 Tomas 提到的不完整的电子邮件地址。

使用以下代码

<?php
$email
= "clifton@example"; // 注意缺少 .com
echo "PHP 版本: ".phpversion().'<br>';
if(
filter_var($email, FILTER_VALIDATE_EMAIL)){
echo
$email.'<br>';
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
}else{
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
}
?>

返回
PHP 版本: 5.2.14 // 在我的服务器上,根据您安装的版本可能有所不同。
bool(false)

而以下代码

<?php
$email
= "[email protected]"; // 注意添加了 .com
echo "PHP 版本: ".phpversion().'<br>';
if(
filter_var($email, FILTER_VALIDATE_EMAIL)){
echo
$email.'<br>';
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
}else{
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
}
?>

返回
PHP 版本: 5.2.14 // 在我的服务器上,根据您安装的版本可能有所不同。
[email protected]
string(16) "[email protected]"

根据文档,此功能仅适用于 PHP 版本 (PHP 5 >= 5.2.0)。所以请确保您的版本正确。

致敬,
Clifton
sebastian dot piskorski at gmail dot com
8 年前
FILTER_VALIDATE_EMAIL 不仅不支持空白折叠和注释。它只检查电子邮件地址的 Addr-spec 部分。否则,它应该将以下地址标记为有效:'Test Example <[email protected]>',因为它根据 RFC 822 是有效的。

另外,地址 "test@localhost" 应该也是有效的,这一点在另一篇笔记中提到过。

您可以使用以下代码进行测试
<?php

$emails
= array(
'Test Example <[email protected]>',
'test@localhost',
'[email protected]'
);

foreach (
$emails as $email) {
echo (
filter_var($email, FILTER_VALIDATE_EMAIL)) ?
"[+] Email '$email' 是有效的\n" :
"[-] Email '$email' 不是有效的\n";
}
?>

PHP 5.3.21 - 7.0.1 的输出
[-] Email 'Test Example <[email protected]>' 不是有效的
[-] Email 'test@localhost' 不是有效的
[+] Email '[email protected]' 是有效的
carlosv775 at gmail dot com
4 年前
看起来 FILTER_VALIDATE_DOMAIN 在 PHP < 7 中不可用

https://3v4l.org/eOPLM
Lech
8 年前
FILTER_VALIDATE_URL 的描述似乎不正确/误导。 "注意,有效 URL 可能不会指定 HTTP 协议" 意味着有效 URL 无法指定 HTTP 协议。我认为 "注意,有效 URL 不需要指定..." 更好。
boan at jfmedier dot dk
2 年前
注意,PHP 8 中删除了一些标志。例如 FILTER_FLAG_HOST_REQUIRED
php dot net at piskvor dot org
13 年前
FILTER_VALIDATE_EMAIL 正在丢弃包含 IDN 的有效电子邮件地址。由于互联网上存在真实的、活动的 IDN,这意味着过滤后的输出过于严格,导致出现假阴性。

Punycode 编码的 IDN 地址可以正确通过过滤器;因此,在检查有效性之前,有必要将电子邮件地址转换为 punycode。
gee2711 at googlemail dot com
6 年前
FILTER_FLAG_QUERY_REQUIRED 无法验证编码的 URL,例如

http://example.com/page.php?q=growing+big

失败,而

http://example.com/page.php?q=big

可以成功验证。因此,任何编码超过一个词的内容都会失败。

在 PHP 版本 7.1 上测试
rowan dot collins at gmail dot com
11 年前
关于没有 . 的 "部分" 地址,域部分的注释在源代码 (在 ext/filter/logical_filters.c 中) 中证明了这种拒绝,因此

* 以下正则表达式基于 Michael Rushton 的正则表达式。
* 但是,它并不完全相同。我改变了它,只考虑可路由的
* 地址为有效。Michael 的正则表达式认为 a@b 是一个有效地址
* 这与 RFC 5321 的 2.3.5 节冲突,该节指出
*
* 仅允许可解析的、完全限定的域名 (FQDN)
* 当域名在 SMTP 中使用时。换句话说,可以
* 解析为 MX RR 或地址 (即 A 或 AAAA) RR (如
* 第 5 节所述) 允许,以及 CNAME RR,其目标可以
* 解析为 MX 或地址 RR。局部别名或
* 非限定名称 必须 不使用。
kizge
8 年前
FILTER_VALIDATE_INT 首先将其值强制转换为字符串,这会导致布尔值和浮点数出现意外结果 (https://bugs.php.net/bug.php?id=72490)

<?php

// 打印 int(1)。
var_dump(filter_var(true, FILTER_VALIDATE_INT));

// ...但它打印 bool(false)。
var_dump(filter_var(false, FILTER_VALIDATE_INT));

// --------

// 打印 bool(false)。
var_dump(filter_var(1.1, FILTER_VALIDATE_INT));

// ...但它打印 int(0)。
var_dump(filter_var(0.0, FILTER_VALIDATE_INT));

// ...但它再次是 bool(false)。
var_dump(filter_var('0.0', FILTER_VALIDATE_INT));

// 也是 bool(false)。
var_dump(filter_var('-0.0', FILTER_VALIDATE_INT));

?>

实时示例:https://3v4l.org/CZW0W

文档没有明确说明这种强制转换如何准确地影响某些输入值的返回值。
rsnell at usgs dot gov
8 年前
注意,如果将 FILTER_NULL_ON_FAILURE 作为标志与 FILTER_VALIDATE_BOOLEAN id 一起使用,则如果外部变量数组中未设置变量名,则不再返回 NULL。它将改为返回 FALSE。在描述中说,当使用 FILTER_NULL_ON_FAILURE 标志时,' 仅对 "0"、"false"、"off"、"no" 和 "" 返回 FALSE' 并且没有提及这种也可以返回 false 的附加状态。这种行为在 filter_input 文档页面中的返回值部分有所提及,但如果您只是在这里查找,则不太有用。

如果不使用 FILTER_NULL_ON_FAILURE,则当外部变量数组中未设置变量名时返回 NULL,对 "1"、"true"、"on" 和 "yes" 返回 TRUE,对其他所有内容返回 FALSE。
Bastien
10 年前
拒绝所谓的“部分域名”是因为“缺少”点,这并不符合 RFC 5321 的 2.3.5 节。

该节规定允许使用 FQDN,而 com、org 或 va 都是(或者可能是)有效的 FQDN。这取决于 DNS,而不是语法。

一些 TDL(尽管很少)有 MX RR,例如“abuse@va”是正确的。
Darth Killer
9 年前
与文档中的描述相反,FILTER_NULL_ON_FAILURE 似乎会影响所有验证过滤器,而不仅仅是 FILTER_VALIDATE_BOOLEAN。我从 PHP 5.2 开始就一直使用它,在 PHP 5.6.8 中它仍然有效。我不知道这是个错误还是预期的行为,如果是预期的行为,那么文档需要修正。

当将该标志用于除 FILTER_VALIDATE_BOOLEAN 之外的验证过滤器时,正如预期的那样,过滤器会在失败时返回 NULL 而不是 FALSE。当使用 filter_input_array() 过滤 POST 表单时,这非常有用,因为你不需要检查哪个字段无效,哪个字段缺失。只需检查返回的元素中是否包含 NULL,就可以完成操作。

<?php
$definition
= array(
'login' => array(
'filter' => FILTER_VALIDATE_STRING,
'flags' => FILTER_NULL_ON_FAILURE
),
'pwd' => FILTER_UNSAFE_RAW
);
$form_data = filter_input_array(INPUT_POST, $definition);
if(
in_array(null, $form_data, true)) {
// 表单无效
} else {
// 表单有效,继续执行
}
?>

当然,如果你需要更精确的错误消息,这种方法就不可行。但我认为知道这一点还是很有好处的。
maruerru at gmail dot com
9 年前
我经常看到类似以下的代码
$value = "12";
if( filter_var($value, FILTER_VALIDATE_INT) )
{
// 验证为整数
}

上面的代码按预期工作,除了当 $value 为“0”时。在这种情况下,它将被解释为 FALSE。

为了得到正确的行为,你不仅要检查它是否等于 (==) false,还要检查它是否与 (===) FALSE 相同。
$value = " 0 ";
if( filter_var($value, FILTER_VALIDATE_INT) === FALSE )
{
// 验证为整数
}

希望我能帮到你。
Andrew Rump
一年前
FILTER_VALIDATE_URL 不支持任何形式的 IDN,例如 rødgrød.dk 或 xn--rdgrd-vuad.dk,即使域名是有效的。
Anonymous
9 年前
FILTER_VALIDATE_FLOAT 的 decimal 选项表示小数点符号 ['。', ',' ]。
Vee W.
五年前
`FILTER_FLAG_EMAIL_UNICODE` 是在 PHP 7.1 中添加的
luca at accomazzi dot net
七年前
关于浮点数的一点忠告。

$t = '312041.25 &euro; instead of 896.70 &euro;';
echo filter_var ($t, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

将返回
312041.25896.70
这可能不是你期望的结果。在 2007 年,有人建议这不可接受(参见 https://bugs.php.net/bug.php?id=40156&edit=2),但它被标记为“不是错误”,因为这些类型的过滤器只应该过滤掉非法字符。
当然,如果你使用 FILTER_VALIDATE_FLOAT,它只会返回输入无效。
andrew dot purkett at gmail dot com
4 年前
请注意,FILTER_FLAG_NO_PRIV_RANGE 标志不会排除 IPv6 命名空间中的 IPv4 私有地址,例如 ::ffff:169.254.169.254。
php at sethsyberg dot com
13 年前
验证浮点数时,必须使用相同/不相同运算符才能正确验证零。

这将无法按预期工作
<?php
$x
= 0;
if (!
filter_var($x, FILTER_VALIDATE_FLOAT)) {
echo
"$x is a valid float";
} else {
echo
"$x is NOT a valid float";
}
?>

这将按预期工作
<?php
$x
= 0;
if (
filter_var($x, FILTER_VALIDATE_FLOAT)!== false) {
echo
"$x is a valid float";
} else {
echo
"$x is NOT a valid float";
}
?>
Wrinkled Cheese
9 年前
验证 URL 时,正如文档中所述,协议不会被验证。但是,它必须存在。

例如

我不希望协议存在。为了验证预期的输入,我必须添加一个“协议”作为前缀,并返回真或假,以及进一步验证输入。

$r = filter_var(''this.doesnt.matter.so.why.is.it.required://'.$host, FILTER_VALIDATE_URL);
return ($r != '' && $r !== false) ? true : false;
Luuk
9 年前
@2:
$value = " 0 ";
$filtered = filter_var($value, FILTER_VALIDATE_INT);
if($filtered || $filtered === 0)
{
// 验证为整数
}

我认为下面的代码更好

$value = "0";
if(filter_var($value, FILTER_VALIDATE_INT) !== false)
{
.....
holger dot ahrens at rittec dot de
2 年前
FILTER_VALIDATE_FLOAT 安全风险 CVE-2021-21708 高风险来自

来自 MITRE 公司,常见漏洞与披露

在 PHP 7.4.x 版本低于 7.4.28,8.0.x 版本低于 8.0.16,以及 8.1.x 版本低于 8.1.3 中,当使用带有 FILTER_VALIDATE_FLOAT 过滤器的过滤器函数和最小/最大限制时,如果过滤器失败,则有可能触发使用已释放的内存,这可能导致崩溃,并可能导致其他内存块被覆盖和远程代码执行。此问题影响:使用带有最小/最大限制的 FILTER_VALIDATE_FLOAT 的代码。

(来源: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-21708)
To Top