Фильтры валидации данных

Список фильтров валидации данных
Идентификатор Имя Параметры Флаги Описание
FILTER_VALIDATE_BOOLEAN, FILTER_VALIDATE_BOOL "boolean" default FILTER_NULL_ON_FAILURE

Возвращает true для значений «1», «true», «on» и «yes». Иначе возвращает false.

Если установлен флаг FILTER_NULL_ON_FAILURE, то false возвращается только для значений «0», «false», «off», «no» и «», а значение null будет возвращёно для нелогических значений.

Перед сравнением строковые значения обрезаются функцией trim().

FILTER_VALIDATE_DOMAIN "validate_domain" default 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" default FILTER_FLAG_EMAIL_UNICODE, FILTER_NULL_ON_FAILURE

Проверяет, представляет ли собой значение действительный адрес электронной почты.

В общем, проверяет addr-spec-синтаксис адреса на соответствие стандарту с » RFC 822, за исключением того, что не поддерживаются комментарии, схлопывание пробельных символов и доменные имена без точек.

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" default 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" default FILTER_NULL_ON_FAILURE Проверяет значение на соответствие корректному MAC-адресу.
FILTER_VALIDATE_REGEXP "validate_regexp" default, regexp FILTER_NULL_ON_FAILURE Проверяет значение на соответствие регулярному выражению regexp, Perl-совместимому регулярному выражению.
FILTER_VALIDATE_URL "validate_url" default 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:// признаётся допустимым, поэтому иногда требуется дополнительная проверка, которая определит, использует ли URL необходимый протокол, например ssh:// или mailto:. Функция признаёт допустимыми URL-адреса, которые состоят только из символов ASCII; интернациональные доменные имена не пройдут проверку.

Замечание:

Вместо значения, которое не прошло проверку, функция подставит значение по умолчанию, если в массиве параметров определена опция default.

Список изменений

Версия Описание
8.0.0 Флаги FILTER_FLAG_SCHEME_REQUIRED и FILTER_FLAG_HOST_REQUIRED для фильтра FILTER_VALIDATE_URL были удалены. Флаги scheme и host были и остаются обязательными.
8.0.0 Добавлена константа FILTER_VALIDATE_BOOL как псевдоним FILTER_VALIDATE_BOOLEAN. Лучше предпочесть FILTER_VALIDATE_BOOL.
7.4.0 Добавлены опции min_range и max_range для фильтра FILTER_VALIDATE_FLOAT.
7.0.0 Добавлен флаг FILTER_FLAG_HOSTNAME и фильтр FILTER_VALIDATE_DOMAIN.

add a note add a note

User Contributed Notes 26 notes

up
45
boy at relaxnow dot nl
12 years ago
FILTER_VALIDATE_URL does not work with URNs, examples of valid URIs according to RFC3986 and if they are accepted by FILTER_VALIDATE_URL:

[PASS] ftp://ftp.is.co.za.example.org/rfc/rfc1808.txt
[PASS] gopher://spinaltap.micro.umn.example.edu/00/Weather/California/Los%20Angeles
[PASS] http://www.math.uio.no.example.net/faq/compression-faq/part1.html
[PASS] mailto:mduerst@ifi.unizh.example.gov
[PASS] news:comp.infosystems.www.servers.unix
[PASS] telnet://melvyl.ucop.example.edu/
[PASS] http://www.ietf.org/rfc/rfc2396.txt
[PASS] ldap://[2001:db8::7]/c=GB?objectClass?one
[PASS] mailto:John.Doe@example.com
[PASS] news:comp.infosystems.www.servers.unix
[FAIL] tel:+1-816-555-1212
[PASS] telnet://192.0.2.16:80/
[FAIL] urn:oasis:names:specification:docbook:dtd:xml:4.1.2
up
13
MR Yekta
4 years ago
since php 7.4
you can use these 3 beautiful conditions for from validation for validation less, great or in range

<?php
/**
* less_than_equal_to
*/
$x = 50;
if (
filter_var($x, FILTER_VALIDATE_FLOAT, ["options" => ["max_range" => 100]]) !== false) {
    echo
"result : $x is less than OR equal to 100";
} else {
    echo
"result : $x is NOT less than OR equal to 100";
}
?>
result : 50 is less than OR equal to 100

<?php
/**
* greater_than_equal_to
*/
$x = 50;
if (
filter_var($x, FILTER_VALIDATE_FLOAT, ["options" => ["min_range" => 100]]) !== false) {
    echo
"result : $x is greater than OR equal to 100";
} else {
    echo
"result : $x is NOT greater than OR equal to 100";
}
?>
result : 50 is NOT greater than OR equal to 100

<?php
/**
* less_than_equal_to && greater_than_equal_to
*/
$x = 50;
if (
filter_var($x, FILTER_VALIDATE_FLOAT, ["options" => ["min_range" => 0 , "max_range"=> 100]]) !== false) {
    echo
"result : $x is in range of 0 to 100";
} else {
    echo
"result : $x in NOT range of 0 to 100";
}
?>
result : 50 is in range of 0 to 100
up
26
bee kay two at em ee dot com
12 years ago
Notably missing is a way to validate text entry as printable,
printable multiline,
or printable and safe (tag free)

FILTER_VALIDATE_TEXT, which validates no special characters
perhaps with FILTER_FLAG_ALLOW_NEWLINE
and FILTER_FLAG_NOTAG to disallow tag starters
up
14
Clifton
13 years ago
FILTER_VALIDATE_EMAIL does NOT allow incomplete e-mail addresses to be validated as mentioned by Tomas.

Using the following code:

<?php
$email
= "clifton@example"; //Note the .com missing
echo "PHP Version: ".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));   
}
?>

Returns:
PHP Version: 5.2.14 //On MY server, may be different depending on which version you have installed.
bool(false)

While the following code:

<?php
$email
= "clifton@example.com"; //Note the .com added
echo "PHP Version: ".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));   
}
?>

Returns:
PHP Version: 5.2.14 //On MY server, may be different depending on which version you have installed.
clifton@example.com
string(16) "clifton@example.com"

This feature is only available for PHP Versions (PHP 5 >= 5.2.0) according to documentation. So make sure your version is correct.

Cheers,
Clifton
up
10
rowan dot collins at gmail dot com
11 years ago
Regarding "partial" addresses with no . in the domain part, a comment in the source code (in ext/filter/logical_filters.c) justifies this rejection thus:

     * The regex below is based on a regex by Michael Rushton.
     * However, it is not identical.  I changed it to only consider routeable
     * addresses as valid.  Michael's regex considers a@b a valid address
     * which conflicts with section 2.3.5 of RFC 5321 which states that:
     *
     *   Only resolvable, fully-qualified domain names (FQDNs) are permitted
     *   when domain names are used in SMTP.  In other words, names that can
     *   be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed
     *   in Section 5) are permitted, as are CNAME RRs whose targets can be
     *   resolved, in turn, to MX or address RRs.  Local nicknames or
     *   unqualified names MUST NOT be used.
up
6
bryanwayb at gmail dot com
9 years ago
It's good to remember that using filter_var is primarily for filtering input values when doing boolean logic comparisons. Take the following:

$value = "12";
if(filter_var($value, FILTER_VALIDATE_INT))
{
    // validated as an int
}

The above works as intended, except when $value = "0". In which case filter_var returns a 0, aka false when used as a boolean.

For the correct behavior, do a zero check.

$value = " 0 ";
$filtered = filter_var($value, FILTER_VALIDATE_INT);
if($filtered || $filtered === 0)
{
    // validated as an int
}
up
3
gee2711 at googlemail dot com
6 years ago
FILTER_FLAG_QUERY_REQUIRED is failing URLs that are encoded e.g.

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

Fails whilst

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

So anything more than one word encoded fails.

Tested on PHP version 7.1
up
4
sebastian dot piskorski at gmail dot com
8 years ago
FILTER_VALIDATE_EMAIL not only doesn't support whitespace folding and comments. It only checks Addr-spec part of email address. Otherwise it should mark such address as valid: 'Test Example <test@example.com>' because it is valid according to RFC 822.

Also address "test@localhost" should be valid. Which is mentioned in another note.

You can test it with this code:
<?php

$emails
= array(
   
'Test Example <test@example.com>',
   
'test@localhost',
   
'test@localhost.com'
);

foreach (
$emails as $email) {
    echo (
filter_var($email, FILTER_VALIDATE_EMAIL)) ?
       
"[+] Email '$email' is valid\n" :
       
"[-] Email '$email' is NOT valid\n";
}
?>

Output for PHP 5.3.21 - 7.0.1 :
[-] Email 'Test Example <test@example.com>' is NOT valid
[-] Email 'test@localhost' is NOT valid
[+] Email 'test@localhost.com' is valid
up
5
Lech
9 years ago
The description for FILTER_VALIDATE_URL seems incorrect/misleading. "Beware a valid URL may not specify the HTTP protocol" implies a valid URL cannot specify the HTTP protocol. I think "Beware a valid URL need not specify..." would be better.
up
1
carlosv775 at gmail dot com
4 years ago
Looks like FILTER_VALIDATE_DOMAIN isn't available on PHP < 7:

https://3v4l.org/eOPLM
up
4
php dot net at piskvor dot org
13 years ago
FILTER_VALIDATE_EMAIL is discarding valid e-mail addresses containing IDN. Since there are real, live IDNs on the Internet, that means the filtered output is too strict, leading to false negatives.

Punycode-encoded IDN addresses pass the filter correctly; so before checking for validity, it is necessary to convert the e-mail address to punycode.
up
1
rsnell at usgs dot gov
8 years ago
Note that if using FILTER_NULL_ON_FAILURE as a flag with the FILTER_VALIDATE_BOOLEAN id then NULL is no longer returned if the variable name is not set in the external variable array. It will instead return FALSE. In the description is says that when using the FILTER_NULL_ON_FAILURE flag that ' FALSE is returned only for "0", "false", "off", "no", and ""' an makes no mention of this additional state that can also return false. The behavior is mentioned on the filter_input documentation page under Return Values but that is not overly helpful if one is just looking here.

If FILTER_NULL_ON_FAILURE is not used then NULL is returned when the variable name is not set in the external variable array, TRUE is returned for "1", "true", "on" and "yes" and FALSE is returned for everything else.
up
2
Bastien
11 years ago
Rejection of so-called partial domains because of "missing" dot is not following section 2.3.5 of RFC 5321.

It says FQDNs are permitted, and com, org, or va are (well, may be) valids FQDNs. It depends on DNS, not on syntax.

Some TDLs (although few of them) have MX RRs, the for example "abuse@va" is correct.
up
1
kizge
8 years ago
FILTER_VALIDATE_INT first casts its value to string which produces unexpected result for bool and float (https://bugs.php.net/bug.php?id=72490):

<?php

// Prints int(1).
var_dump(filter_var(true, FILTER_VALIDATE_INT));

// ...but this prints bool(false).
var_dump(filter_var(false, FILTER_VALIDATE_INT));

// --------

// Prints bool(false).
var_dump(filter_var(1.1, FILTER_VALIDATE_INT));

// ...but this prints int(0).
var_dump(filter_var(0.0, FILTER_VALIDATE_INT));

// ...but this again is bool(false).
var_dump(filter_var('0.0', FILTER_VALIDATE_INT));

// Also bool(false).
var_dump(filter_var('-0.0', FILTER_VALIDATE_INT));

?>

Live sample: https://3v4l.org/CZW0W

The docs are not clear on how exactly this casting affects the result for certain input values.
up
1
maruerru at gmail dot com
9 years ago
Often I see some code like the following:
$value = "12";
if( filter_var($value, FILTER_VALIDATE_INT) )
{
    // validated as an int
}

The above works as intended, except when $value is "0". In the above case it will be interpreted as FALSE.

For the correct behavior,  you have not only to check if it is equal (==) to false, but also identic (===) to FALSE:
$value = " 0 ";
if( filter_var($value, FILTER_VALIDATE_INT)  === FALSE )
{
    // validated as an int
}

I hope, I could help.
up
0
Andrew Rump
2 years ago
FILTER_VALIDATE_URL do not support IDN in any form, i.e., neither rødgrød.dk nor xn--rdgrd-vuad.dk even though the domain is active.
up
1
Anonymous
9 years ago
FILTER_VALIDATE_FLOAT, decimal option mean decimal notation['.', ','].
up
0
boan at jfmedier dot dk
3 years ago
Note that some flags are removed in PHP 8. E.g. FILTER_FLAG_HOST_REQUIRED
up
0
Vee W.
5 years ago
`FILTER_FLAG_EMAIL_UNICODE` was added in PHP 7.1
up
0
Darth Killer
9 years ago
Contrary to what documentation implies, the FILTER_NULL_ON_FAILURE seem to affect any validation filter, not just FILTER_VALIDATE_BOOLEAN. I've been using that since PHP 5.2, and as of PHP 5.6.8 it still works. I have no clue if it's a blug or if it is as intended, in which case the documentation needs to be fixed.

When the flag is used on a validation filter other than FILTER_VALIDATE_BOOLEAN, as expected the filter will return NULL instead of FALSE upon failure. This is quite useful when filtering a POST form with filter_input_array(), where you don't want to check what field is invalid and what field is missing. Just check if NULL is among the returned elements and you're done.

<?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)) {
  
// invalid form
} else {
  
// valid form, let's proceed
}
?>

Of course, if you want more precise error messages that approach won't work. But it's still good to know, i believe.
up
-2
luca at accomazzi dot net
7 years ago
A word to the wise regarding floats.

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

will return
312041.25896.70
which is likely not what you were expecting. In 2007 someone suggested it's not acceptable (see https://bugs.php.net/bug.php?id=40156&edit=2) but it was flagged "not a bug" because these kind of filters are only supposed to filter out illegal characters.
Of course if you were to use FILTER_VALIDATE_FLOAT it would just return that the input is not valid.
up
-4
php at sethsyberg dot com
13 years ago
When validating floats, you must use the Identical/Not identical operators for proper validation of zeros:

This will not work as expected:
<?php
$x
= 0;
if (!
filter_var($x, FILTER_VALIDATE_FLOAT)) {
    echo
"$x is a valid float";
} else {
    echo
"$x is NOT a valid float";
}
?>

This will work as expected:
<?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";
}
?>
up
-3
Wrinkled Cheese
9 years ago
When validating a URL, as documented, the protocol is not validated.  However, it is required to be present.

For example:

I don't expect a protocol to be present.  To validate expected input I have to add a "protocol" as a prefix, and return true or false, and further validate the input.

$r = filter_var(''this.doesnt.matter.so.why.is.it.required://'.$host, FILTER_VALIDATE_URL);
return ($r != '' && $r !== false) ? true : false;
up
-7
Luuk
9 years ago
@2:
$value = " 0 ";
$filtered = filter_var($value, FILTER_VALIDATE_INT);
if($filtered || $filtered === 0)
{
    // validated as an int
}

I think next code is better:

$value = "0";
if(filter_var($value, FILTER_VALIDATE_INT) !== false)
{
  .....
up
-2
andrew dot purkett at gmail dot com
4 years ago
Please note that the FILTER_FLAG_NO_PRIV_RANGE flag does not exclude IPv4 private addresses in the IPv6 namespace, such as ::ffff:169.254.169.254.
up
-3
holger dot ahrens at rittec dot de
2 years ago
FILTER_VALIDATE_FLOAT Security Risk CVE-2021-21708 High Risk from

Warning from MITRE Corporation, Common Vulnerabilities and Exposures:

In PHP versions 7.4.x below 7.4.28, 8.0.x below 8.0.16, and 8.1.x below 8.1.3, when using filter functions with FILTER_VALIDATE_FLOAT filter and min/max limits, if the filter fails, there is a possibility to trigger use of allocated memory after free, which can result it crashes, and potentially in overwrite of other memory chunks and RCE. This issue affects: code that uses FILTER_VALIDATE_FLOAT with min/max limits.

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