- Функции фильтрации данных
- PHP Filters
- The PHP Filter Extension
- Example
- Why Use Filters?
- PHP filter_var() Function
- Sanitize a String
- Example
- Hello World!
- Validate an Integer
- Example
- Tip: filter_var() and Problem With 0
- Example
- Validate an IP Address
- Example
- Sanitize and Validate an Email Address
- Example
- Sanitize and Validate a URL
- Example
- Complete PHP Filter Reference
- Php data filter class
Функции фильтрации данных
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’ );
PHP Filters
Validating data = Determine if the data is in proper form.
Sanitizing data = Remove any illegal character from the data.
The PHP Filter Extension
PHP filters are used to validate and sanitize external input.
The PHP filter extension has many of the functions needed for checking user input, and is designed to make data validation easier and quicker.
The filter_list() function can be used to list what the PHP filter extension offers:
Example
Why Use Filters?
Many web applications receive external input. External input/data can be:
- User input from a form
- Cookies
- Web services data
- Server variables
- Database query results
You should always validate external data!
Invalid submitted data can lead to security problems and break your webpage!
By using PHP filters you can be sure your application gets the correct input!
PHP filter_var() Function
The filter_var() function both validate and sanitize data.
The filter_var() function filters a single variable with a specified filter. It takes two pieces of data:
Sanitize a String
The following example uses the filter_var() function to remove all HTML tags from a string:
Example
$str = «
Hello World!
«;
$newstr = filter_var($str, FILTER_SANITIZE_STRING);
echo $newstr;
?>?php
Validate an Integer
The following example uses the filter_var() function to check if the variable $int is an integer. If $int is an integer, the output of the code below will be: «Integer is valid». If $int is not an integer, the output will be: «Integer is not valid»:
Example
if (!filter_var($int, FILTER_VALIDATE_INT) === false) echo(«Integer is valid»);
> else echo(«Integer is not valid»);
>
?>
Tip: filter_var() and Problem With 0
In the example above, if $int was set to 0, the function above will return «Integer is not valid». To solve this problem, use the code below:
Example
if (filter_var($int, FILTER_VALIDATE_INT) === 0 || !filter_var($int, FILTER_VALIDATE_INT) === false) echo(«Integer is valid»);
> else echo(«Integer is not valid»);
>
?>
Validate an IP Address
The following example uses the filter_var() function to check if the variable $ip is a valid IP address:
Example
if (!filter_var($ip, FILTER_VALIDATE_IP) === false) echo(«$ip is a valid IP address»);
> else echo(«$ip is not a valid IP address»);
>
?>
Sanitize and Validate an Email Address
The following example uses the filter_var() function to first remove all illegal characters from the $email variable, then check if it is a valid email address:
Example
// Remove all illegal characters from email
$email = filter_var($email, FILTER_SANITIZE_EMAIL);
// Validate e-mail
if (!filter_var($email, FILTER_VALIDATE_EMAIL) === false) echo(«$email is a valid email address»);
> else echo(«$email is not a valid email address»);
>
?>
Sanitize and Validate a URL
The following example uses the filter_var() function to first remove all illegal characters from a URL, then check if $url is a valid URL:
Example
// Remove all illegal characters from a url
$url = filter_var($url, FILTER_SANITIZE_URL);
// Validate url
if (!filter_var($url, FILTER_VALIDATE_URL) === false) echo(«$url is a valid URL»);
> else echo(«$url is not a valid URL»);
>
?>
Complete PHP Filter Reference
For a complete reference of all filter functions, go to our complete PHP Filter Reference. Check each filter to see what options and flags are available.
The reference contains a brief description, and examples of use, for each function!
Php data filter class
Here is an example, since I cannot find one through out php.net»
/**
* Strip whitespace (or other non-printable characters) from the beginning and end of a string
* @param string $value
*/
function trimString ( $value )
return trim ( $value );
>
$loginname = filter_input ( INPUT_POST , ‘loginname’ , FILTER_CALLBACK , array( ‘options’ => ‘trimString’ ));
NOTE: dont wrap PHP function in closure as writed in «top» comment
$str = filter_input ( INPUT_GET , ‘str’ , FILTER_CALLBACK , [ ‘options’ => ‘trim’ ]);
?>
Are you also struggling with how to send arguments into the FILTER_CALLBACK.
Lets say you like to have a collection of custom filters that you can use in filter_var, filter_var_array and so on, but you want be able to call the new filters with different arguments, as you can in filter_var.
The easiest way to do this is to make a new class with all your custom filters. Then construct the class with your arguments inside filter_var argument array and enter the method in your class you like to run after.
If you send the argument as an array it is easy to make default values. But you can pass as many arguments you want and in any type, with this solution.
Example:
/**
* Class CustomFilters
* Custom filters for filter_var, filter_var_array, filter_input, filter_input_array
*/
class CustomFilters private $options = array();
public function __construct (array $options =array()) $this -> options = $options ;
>
/**
* Returns the default options merged with the construction options
* @param array $defaults
* @return array
*/
private function get_options (array $defaults ) return array_merge ( $defaults , $this -> options );
>
/**
* Checks if a value is in a range
* @param mixed $val Value provided by filter_var
* @return mixed
*/
public function FILTER_STEP_RANGE ( $val ) $options = $this -> get_options (
// default options
array(
«min_range» => 1 ,
«max_range» => 10 ,
«step» => 1 ,
«default» => null , // Value to return on fail
«strict» => false , // Check value for correct type
«cast» => false // Cast the value in a certain type
)
);
if( in_array ( $val , range ( $options [ «min_range» ], $options [ «max_range» ], $options [ «step» ]), $options [ «strict» ]))
return $val ;
>else return $options [ «default» ];
>
>
/**
* Checks if a value is in array
* @param mixed $val Value provided by filter_var
* @return mixed
*/
public function FILTER_ENUM ( $val ) $options = $this -> get_options (
// default options
array(
«values» => array(),
«strict» => false , // Value to return on fail
«default» => null , // Check value for correct type
«cast» => false // Cast the value in a certain type
)
);
if( in_array ( $val , $options [ «values» ], $options [ «strict» ]))
return $val ;
>else return $options [ «default» ];
>
>
>
$data = array(
«range1» => «200» ,
«range2» => 25 ,
«enum» => «yes»
);
$args = array(
«range1» => array(
«filter» => FILTER_CALLBACK ,
«options» => array(
new CustomFilters (array( «min_range» => 10 , «max_range» => 600 , «step» => 10 , «default» => 120 ,
«cast» => «integer» )),
‘FILTER_STEP_RANGE’
)
),
«range2» => array(
«filter» => FILTER_CALLBACK ,
«options» => array(
new CustomFilters (array( «min_range» => 0 , «max_range» => 1 , «step» => .1 , «default» => .5 ,
«cast» => «float» )),
‘FILTER_STEP_RANGE’
)
),
«enum» => array(
«filter» => FILTER_CALLBACK ,
«options» => array(
new CustomFilters (array( «values» => array( «yes» , «no» , «Yes» , «No» ), «cast» => «string» )),
‘FILTER_ENUM’
)
)
);
var_dump ( filter_var_array ( $data , $args ) );
?>
Returns:
array(3) [«range1»] => int(200)
[«range2»] => float(0.5)
[«enum»] => string(3) «yes»
>
Here’s how to create callable functions with parameters. These are functions that return closures. When you call them, you supply the known parameters, and it returns a function that will accept the value from filter_input() or filter_input_array().
function filter_sanitize_int_range_generator ( $low , $high ) return function( $value = null ) use ( $low , $high ) $v = intval ( $value );
if ( $v < $low ) return false ;
if ( $v > $high ) return false ;
return $v ;
>;
>
function filter_sanitize_string_in_array_generator ( $array ) return function( $value = null ) use ( $array ) if (! is_string ( $value )) return false ;
if ( in_array ( $value , $array )) return $value ;
return false ;
>;
>
echo «TESTING RANGE\n» ;
$fun = filter_sanitize_int_range_generator ( 1 , 10 );
var_dump ( $fun ( 5 )); // 5
var_dump (( filter_sanitize_int_range_generator ( 1 , 10 ))( 0 )); // false
var_dump (( filter_sanitize_int_range_generator ( 1 , 10 ))( 1 )); // 1
var_dump (( filter_sanitize_int_range_generator ( 1 , 10 ))( 10 )); // 10
var_dump (( filter_sanitize_int_range_generator ( 1 , 10 ))( 11 )); // false
var_dump ( $fun ()); // false
echo «TESTING IN ARRAY\n» ;
$fun = filter_sanitize_string_in_array_generator ([ ‘cat’ , ‘dog’ , ‘bird’ ]);
var_dump ( $fun ( ‘cat’ )); // cat
var_dump ( $fun ( ‘dog’ )); // dog
var_dump ( $fun ( ‘bird’ )); // bird
var_dump ( $fun ( ‘fish’ )); // false
var_dump ( $fun ()); // false
// use it like this
filter_input ( INPUT_GET , ‘month’ , FILTER_CALLBACK , array( «callable» => filter_sanitize_int_range_generator ( 1 , 12 ) ) );
The supplied callback function may also be a class method. (since 5.4.0 ?)
To use a method you need to set the options param to an array with two values: the first is the object and the second is the method name.
/**
* @property-read $language
*/
class GetInputStore private $allowed_languages = array( ‘en’ , ‘fr’ , ‘de’ , ‘nl’ /*, . */ );
private $language ;
public function __construct () $this -> language = filter_input ( INPUT_GET , ‘language’ , FILTER_CALLBACK , array( ‘options’ => array( $this , ‘get_language_code’ )));
>
public function __get ( $name ) switch( $name ) case ‘language’ : return $this -> language ;
default : throw new Exception ( «The GetInputStore class doesn’t support GET param \» $name \»» );
>
>
private function get_language_code ( $code ) if( in_array ( $code , $this -> allowed_languages )) return $code ;
> else return ‘en’ ;
>
>
>
?>
Some useful custom filters:
function sanitizeOptions ( $array , $default ) return function( $value = null ) use ( $array , $default ) if ( in_array ( $value , $array )) return $value ;
return $default ;
>;
>
function sanitizeKey ( $value ) return strtolower ( preg_replace ( ‘/[^a-zA-Z0-9-_\.]/’ , » , $value ));
>
filter_var ( $format , FILTER_CALLBACK , array(
«options» => sanitizeOptions ([ ‘html’ , ‘json’ , ‘blob’ ], ‘json’ )
));
filter_var ( $format , FILTER_CALLBACK , array(
«options» => ‘sanitizeKey’
));