Filter Functions
I recommend you to use the FILTER_REQUIRE_SCALAR (or FILTER_REQUIRE_ARRAY) flags, since you can use array-brackets both to access string offsets and array-element — however, not only this can lead to unexpected behaviour. Look at this example:
$image = basename ( filter_input ( INPUT_GET , ‘src’ , FILTER_UNSAFE_RAW , FILTER_FLAG_STRIP_LOW ));
// further checks
?>
/script.php?src[0]=foobar will cause a warning. 🙁
Hence my recommendation:
$image = basename ( filter_input ( INPUT_GET , ‘src’ , FILTER_UNSAFE_RAW , FILTER_REQUIRE_SCALAR | FILTER_FLAG_STRIP_LOW ));
// further checks
?>
Also notice that filter functions are using only the original variable values passed to the script even if you change the value in super global variable ($_GET, $_POST, . ) later in the script.
echo filter_input ( INPUT_GET , ‘var’ ); // print ‘something’
echo $_GET [ ‘var’ ]; // print ‘something’
$_GET [ ‘var’ ] = ‘changed’ ;
echo filter_input ( INPUT_GET , ‘var’ ); // print ‘something’
echo $_GET [ ‘var’ ]; // print ‘changed’
?>
In fact, external data are duplicated in SAPI before the script is processed and filter functions don’t use super globals anymore (as explained in Filter tutorial bellow, section ‘How does it work?’).
There is an undocumented filter flag for FILTER_VALIDATE_BOOLEAN. The documentation implies that it will return NULL if the value doesn’t match the allowed true/false values. However this doesn’t happen unless you give it the FILTER_NULL_ON_FAILURE flag like this:
$value = ‘car’ ;
$result = filter_var ( $value , FILTER_VALIDATE_BOOLEAN , FILTER_NULL_ON_FAILURE );
?>
In the above $result will equal NULL. Without the extra flag it would equal FALSE, which isn’t usually a desired result for this specific filter.
Just to note that «server and env support may not work in all sapi, for filter 0.11.0 or php 5.2.0» as mentioned in Filter tutorial bellow.
The workaround is obvious:
Instead of
$var = filter_input ( INPUT_SERVER , ‘SERVER_NAME’ , FILTER_DEFAULT );
?>
use
$var = filter_var (isset( $_SERVER [ ‘SERVER_NAME’ ]) ? $_SERVER [ ‘SERVER_NAME’ ] : NULL , FILTER_DEFAULT );
?>
Beware, the FILTER_SANITIZE_STRING flag functions much like strip_tags, so < will get filtered from input regardless of it's actually part of a tag. We were getting unexepected results with a graphic library we wrote when trying to print < on a dynamic button. The url came in something like ?string=%3C (<) but after filter ran it was empty. To get around this, you could use FILTER_UNSAFE_RAW on that one param.
Below is some code using filter API to restrict access to LAN by IPv4 private address range.
These notes may save someone else a little time:
filter_input_array() is useless for running multiple filters on the same key.
No way to chain or negate filters.
/* Merciful comment! */
function FILTER_NEGATE_HACK ( $_ )
if (! client_is_private_ipv4 ())
exit( ‘This application is restricted to local network users’ );
filter_var
Value to filter. Note that scalar values are converted to string internally before they are filtered.
The ID of the filter to apply. The Types of filters manual page lists the available filters.
If omitted, FILTER_DEFAULT will be used, which is equivalent to FILTER_UNSAFE_RAW . This will result in no filtering taking place by default.
Associative array of options or bitwise disjunction of flags. If filter accepts options, flags can be provided in «flags» field of array. For the «callback» filter, callable type should be passed. The callback must accept one argument, the value to be filtered, and return the value after filtering/sanitizing it.
// for filters that accept options, use this format
$options = array(
‘options’ => array(
‘default’ => 3 , // value to return if the filter fails
// other options here
‘min_range’ => 0
),
‘flags’ => FILTER_FLAG_ALLOW_OCTAL ,
);
$var = filter_var ( ‘0755’ , FILTER_VALIDATE_INT , $options );
?php
// for filters that only accept flags, you can pass them directly
$var = filter_var ( ‘oops’ , FILTER_VALIDATE_BOOLEAN , FILTER_NULL_ON_FAILURE );
// for filters that only accept flags, you can also pass as an array
$var = filter_var ( ‘oops’ , FILTER_VALIDATE_BOOLEAN ,
array( ‘flags’ => FILTER_NULL_ON_FAILURE ));
// callback validate filter
function foo ( $value )
// Expected format: Surname, GivenNames
if ( strpos ( $value , «, » ) === false ) return false ;
list( $surname , $givennames ) = explode ( «, » , $value , 2 );
$empty = (empty( $surname ) || empty( $givennames ));
$notstrings = (! is_string ( $surname ) || ! is_string ( $givennames ));
if ( $empty || $notstrings ) return false ;
> else return $value ;
>
>
$var = filter_var ( ‘Doe, Jane Sue’ , FILTER_CALLBACK , array( ‘options’ => ‘foo’ ));
?>
Return Values
Returns the filtered data, or false if the filter fails.
Examples
Example #1 A filter_var() example
var_dump ( filter_var ( ‘bob@example.com’ , FILTER_VALIDATE_EMAIL ));
var_dump ( filter_var ( ‘http://example.com’ , FILTER_VALIDATE_URL , FILTER_FLAG_PATH_REQUIRED ));
?>?php
The above example will output:
string(15) "bob@example.com" bool(false)
Example #2 Filter an array example
var_dump ( filter_var ( $emails , FILTER_VALIDATE_EMAIL , FILTER_REQUIRE_ARRAY ));
?>
The above example will output:
array(3) < [0]=>string(15) "bob@example.com" [1]=> string(18) "test@example.local" [2]=> bool(false) >
See Also
- filter_var_array() — Gets multiple variables and optionally filters them
- filter_input() — Gets a specific external variable by name and optionally filters it
- filter_input_array() — Gets external variables and optionally filters them
- Types of filters
Ещё раз о filter var / PHP. Особенности и фичи
Очень часто приходится сталкиваться с простейшей задачей — валидацией данных из формы или любых других источников (кукисы, заголовок запроса, etc.) И каждый раз 95% разработчиков городят какие-то неимоверные велосипеды (регулярные выражения, «уникальные» алгоритмы хеширования паролей, etc). И каждый раз мне приходится рассказывать о такой невероятно полезной и нужной функции php — filter_var!
Итак, встречаем, встроенная функция валидации данных.
Эта замечательная функция появилась уже давно, в PHP 5.2.0, но до сих пор, очень малый процент разработчиков применяют её, предпочитая свои велосипеды. И это очень зря, ведь Вы используете готовые фреймворки, ORM и другие инструменты? Так почему Вы не валидируете данные встроенными методами?
Фильтры валидации данных
- FILTER_VALIDATE_BOOLEAN — проверяет, что значение является корректным булевым значением. Использует неявное приведение типов. Примеры валидных значений: «1», «true», «on», «yes».
- FILTER_VALIDATE_EMAIL — проверяет, что значение является корректным email.
- FILTER_VALIDATE_FLOAT — проверяет, что значение является корректным числом с плавающей точкой.
- FILTER_VALIDATE_INT — проверяет, что значение является корректным целым числом. Дополнительно можно проверить входит ли значение в определенный диапазон.
- FILTER_VALIDATE_IP — проверяет, что значение является корректным ip-адресом (v4 или v6). Дополнительно можно проверить, что IP соответствует протоколу IPv4 или IPv6, а также отсутствие вхождения в частные или зарезервированные диапазоны.
- FILTER_VALIDATE_REGEXP — Проверяет значение на соответствие regexp, Perl-совместимому регулярному выражению.
- FILTER_VALIDATE_URL — проверяет, что значение является корректным url адресом (в соответствии с RFC 2396).
- FILTER_VALIDATE_INT
- Числа +0 и -0 не пройдут проверку на целые числа, но пройдут ее на числа с плавающей точкой.
- Корректная ссылка может не содержать HTTP-протокол , т.е. необходима еще одна проверка, определяющая наличие необходимого протокола у ссылки, например, ssh:// или mailto:.
- Функция работает только с ASCII-ссылками, таким образом, интернациональные доменные имена (содержащие не-ASCII символы) не пройдут проверку.
- Доменная зона не проверяется на реальность, так что адрес вида [email protected] пройдет валидацию (привет зонам верхнего уровня аля .yandex).
Примеры
[email protected]', FILTER_VALIDATE_EMAIL); // [email protected] filter_var('d#fh$df%[email protected]', FILTER_VALIDATE_EMAIL); // d#fh$df%[email protected] то есть верно! filter_var('[email protected]', FILTER_VALIDATE_EMAIL); // [email protected] то есть верно! filter_var('имя-на-русском@сайтец.рф', FILTER_VALIDATE_EMAIL); // false filter_var('@site.b', FILTER_VALIDATE_EMAIL); // false // FILTER_VALIDATE_FLOAT filter_var(1, FILTER_VALIDATE_FLOAT); // 1 filter_var(0, FILTER_VALIDATE_FLOAT); // 0 filter_var(1.1, FILTER_VALIDATE_FLOAT); // 1.1 filter_var(true, FILTER_VALIDATE_FLOAT); // 1 filter_var( '1,1', FILTER_VALIDATE_FLOAT, array('options' => array('decimal' => ',')) ); // 1.1 filter_var('1,1', FILTER_VALIDATE_FLOAT); // false filter_var('1,000,000', FILTER_VALIDATE_FLOAT); // false filter_var('1,000,000', FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND); // 1000000 // FILTER_VALIDATE_INT filter_var(1, FILTER_VALIDATE_INT); // 1 filter_var(0, FILTER_VALIDATE_INT); // 0 filter_var(true, FILTER_VALIDATE_INT); // 1 filter_var('3', FILTER_VALIDATE_INT); // 3 filter_var('3.2', FILTER_VALIDATE_INT); // false filter_var( 22, FILTER_VALIDATE_INT, array('options' => array('min_range' => 30)) ); // false filter_var( 32, FILTER_VALIDATE_INT, array('options' => array('min_range' => 30)) ); // 32 // FILTER_FLAG_ALLOW_OCTAL filter_var(032, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_OCTAL); // 26 // FILTER_FLAG_ALLOW_HEX filter_var(0x32, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX); // 50 // FILTER_VALIDATE_IP filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP); // 127.0.0.1 filter_var('10.0.0.0', FILTER_VALIDATE_IP); // 10.0.0.0 // FILTER_FLAG_IPV6 filter_var('10.0.0.0', FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); // false filter_var( '2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d', FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ); // 2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d // FILTER_FLAG_NO_PRIV_RANGE filter_var('10.0.0.0', FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE); // false filter_var('33.35.73.255', FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE); // 33.35.73.255 // FILTER_FLAG_NO_RES_RANGE filter_var('0.0.0.0', FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE); // false filter_var('10.0.0.0', FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE); // 10.0.0.0 // FILTER_VALIDATE_REGEXP filter_var( 'hello world', FILTER_VALIDATE_REGEXP, array('options'=>array('regexp'=>'/^h/is')) ); // hello world filter_var( 'world hello', FILTER_VALIDATE_REGEXP, array('options'=>array('regexp'=>'/^h/is')) ); // false filter_var( 'hello world', FILTER_VALIDATE_REGEXP, array('options'=>array('regexp'=>'/7+/is')) ); // false filter_var( '22 543 24', FILTER_VALIDATE_REGEXP, array('options'=>array('regexp'=>'/1+/is')) ); // 22 543 24 // FILTER_VALIDATE_URL filter_var('http://somesite.com', FILTER_VALIDATE_URL); // http://somesite.com filter_var('http://какой-то-сайт.рф', FILTER_VALIDATE_URL); // false filter_var('http://#%$%#^^.com', FILTER_VALIDATE_URL); // false filter_var('somesite.com', FILTER_VALIDATE_URL); // false filter_var('torrent://somesite.com', FILTER_VALIDATE_URL); // torrent://somesite.com // FILTER_FLAG_PATH_REQUIRED filter_var( 'http://somesite.com', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED ); // false filter_var( 'http://somesite.com/test', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED ); // http://somesite.com/test // FILTER_FLAG_QUERY_REQUIRED filter_var( 'http://somesite.com', FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED ); // false filter_var( 'http://somesite.com?test', FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED ); // http://somesite.com?test // FILTER_FLAG_PATH_REQUIRED | FILTER_FLAG_QUERY_REQUIRED filter_var( 'http://somesite.com/test?test', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED | FILTER_FLAG_QUERY_REQUIRED ); // http://somesite.com?test ?>