Sanitize filters

List of filters for sanitization
ID Name Flags Description
FILTER_SANITIZE_EMAIL "email"   Remove all characters except letters, digits and !#$%&'*+-=?^_`{|}~@.[].
FILTER_SANITIZE_ENCODED "encoded" FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_BACKTICK, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH URL-encode string, optionally strip or encode special characters.
FILTER_SANITIZE_MAGIC_QUOTES "magic_quotes"   Apply addslashes(). (DEPRECATED as of PHP 7.3.0 and REMOVED as of PHP 8.0.0, use FILTER_SANITIZE_ADD_SLASHES instead.)
FILTER_SANITIZE_ADD_SLASHES "add_slashes"   Apply addslashes(). (Available as of PHP 7.3.0)
FILTER_SANITIZE_NUMBER_FLOAT "number_float" FILTER_FLAG_ALLOW_FRACTION, FILTER_FLAG_ALLOW_THOUSAND, FILTER_FLAG_ALLOW_SCIENTIFIC Remove all characters except digits, +- and optionally .,eE.
FILTER_SANITIZE_NUMBER_INT "number_int"   Remove all characters except digits, plus and minus sign.
FILTER_SANITIZE_SPECIAL_CHARS "special_chars" FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_BACKTICK, FILTER_FLAG_ENCODE_HIGH HTML-encode '"<>& and characters with ASCII value less than 32, optionally strip or encode other special characters.
FILTER_SANITIZE_FULL_SPECIAL_CHARS "full_special_chars" FILTER_FLAG_NO_ENCODE_QUOTES, Equivalent to calling htmlspecialchars() with ENT_QUOTES set. Encoding quotes can be disabled by setting FILTER_FLAG_NO_ENCODE_QUOTES. Like htmlspecialchars(), this filter is aware of the default_charset and if a sequence of bytes is detected that makes up an invalid character in the current character set then the entire string is rejected resulting in a 0-length string. When using this filter as a default filter, see the warning below about setting the default flags to 0.
FILTER_SANITIZE_STRING "string" FILTER_FLAG_NO_ENCODE_QUOTES, FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_BACKTICK, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH, FILTER_FLAG_ENCODE_AMP Strip tags and HTML-encode double and single quotes, optionally strip or encode special characters. Encoding quotes can be disabled by setting FILTER_FLAG_NO_ENCODE_QUOTES.
FILTER_SANITIZE_STRIPPED "stripped"   Alias of "string" filter.
FILTER_SANITIZE_URL "url"   Remove all characters except letters, digits and $-_.+!*'(),{}|\\^~[]`<>#%";/?:@&=.
FILTER_UNSAFE_RAW "unsafe_raw" FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_BACKTICK, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH, FILTER_FLAG_ENCODE_AMP Do nothing, optionally strip or encode special characters. This filter is also aliased to FILTER_DEFAULT.

Warning

When using one of these filters as a default filter either through your ini file or through your web server's configuration, the default flags is set to FILTER_FLAG_NO_ENCODE_QUOTES. You need to explicitly set filter.default_flags to 0 to have quotes encoded by default. Like this:

Example #1 Configuring the default filter to act like htmlspecialchars

filter.default = full_special_chars
filter.default_flags = 0

更新日志

版本 说明
8.0.0 FILTER_SANITIZE_MAGIC_QUOTES has been removed.
7.3.0 FILTER_SANITIZE_ADD_SLASHES was added as a replacement for FILTER_SANITIZE_MAGIC_QUOTES
7.3.0 FILTER_SANITIZE_MAGIC_QUOTES has been deprecated.

User Contributed Notes

ipse at sergiosantos dot me 02-Dec-2020 04:49
Although it's specifically mentioned in the above documentation, because many seem to find this unintuitive it's worth pointing out that FILTER_SANITIZE_NUMBER_FLOAT will remove the decimal character unless you specify FILTER_FLAG_ALLOW_FRACTION:

<?php
$number_string
= '12.34';

echo
filter_var( $number_string, FILTER_SANITIZE_NUMBER_FLOAT ); // 1234

echo filter_var( $number_string, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ); // 12.34
?>
Anonymous 20-Jul-2020 05:29
<?php
 
/*
     filter all ascii and save juste 0-9 a-Z and @ . _
*/

echo alphanum('abcdefghABCDEFGH0123456789/!:;@._');
// return abcdefghABCDEFGH0123456789@._

function alphanum( $string , $x=''){
       
$h=strlen($string);
        for(
$a=0; $a<$h; $a++) {
           
$i = ord($string[$a]);
            if(
                (
$i==46) || // .
               
($i==64) || // @
               
($i==95) || // _
               
($i > 47 && $i < 58) || //0123456789
               
($i > 64 && $i < 91) || //ABCDEFGH..Z
               
($i > 96 && $i < 123)   //abcdefgh..z
            
) { $x .= $string[$a]; }   
        }
        return
$x;
    }

?>
Rodrigo Guariento 13-Feb-2020 11:55
To get ONLY numbers from a string use this code:
    echo preg_replace('/[^0-9]/', '', '123456-789');
anonymous 31-Jan-2020 12:55
In the "FILTER_SANITIZE_URL" section where it says, "Remove all characters except letters, digits and $-_.+!*'(),{}|\\^~[]`<>#%";/?:@&=." is there a reason why there is a double backslash (\\)? Shouldn't there only be one backslash if it's saying that backslashes are allowed?
darren at daz-web dot com 12-Nov-2018 12:31
For those looking for a simple way around filtering POST forms that have textarea elements in them. If you also need tab for example you can extend quite easily.

<?php
//create an array of all relevant textareas
$textareas = array("ta1");

foreach(
$_POST as $k => $v)
    {
       
$v = trim($v);//so we are sure it is whitespace free at both ends
   
        //preserve newline for textarea answers
       
if(in_array($k,$textareas))$v=str_replace("\n","[NEWLINE]",$v);
   
       
//sanitise string
       
$v = filter_var($v, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_BACKTICK);
   
       
//now replace the placeholder with the original newline
       
$_POST[$k] = str_replace("[NEWLINE]","\n",$v);
    }

//simple form for testing submital

?><!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Filter test</title>
</head>

<body>
   
<form action="" method="post">
    <p>
        <textarea name="ta1" cols="30" rows="10"><?php echo $_POST['ta1']; ?></textarea>
    </p>
    <p>
        <input type="text" name="txt1" size="30" value="<?php echo $_POST['txt1']; ?>" />
    </p>
    <p>
        <input type="submit" />   
    </p>
    </form>

</body>
   
</html>
AntonioPrimera 04-Aug-2016 01:12
Please be aware that when using filter_var() with FILTER_SANITIZE_NUMBER_FLOAT and FILTER_SANITIZE_NUMBER_INT the result will be a string, even if the input value is actually a float or an int.

Use FILTER_VALIDATE_FLOAT and FILTER_VALIDATE_INT, which will convert the result to the expected type.
Ruth 03-Jun-2016 02:59
This is an example for a form having a group of checkboxes besides a lot of other inputs:

$args = array(
    'details' => array(
        'name' => 'details[]',
        'filter' => FILTER_SANITIZE_STRING,
        'flags'  => FILTER_REQUIRE_ARRAY
    )
    // ,
    // a lot of other stuff here (all the form's elements)
);
$myInputs = filter_input_array( INPUT_GET, $args, true );

where the checkboxes are (their form is in a page that reloads itself):

<label>
    <input type="checkbox" name="details[]" value="A" <?php if (in_array( "A", $myInputs['details'] )) { echo 'checked'; } ?>>
    Show A
</label>
<label>
    <input type="checkbox" name="details[]" value="B" <?php if (in_array( "B", $myInputs['details'] )) { echo 'checked'; } ?>>
    Show B
</label>
<label>
    <input type="checkbox" name="details[]" value="C" <?php if (in_array( "C", $myInputs['details'] )) { echo 'checked'; } ?>>
    Show C
</label>
<label>
    <input type="checkbox" name="details[]" value="D" <?php if (in_array( "D", $myInputs['details'] )) { echo 'checked'; } ?>>
    Show D
</label>
Willscrlt 10-Mar-2016 10:11
To include multiple flags, simply separate the flags with vertical pipe symbols.

For example, if you want to use filter_var() to sanitize $string with FILTER_SANITIZE_STRING and pass in FILTER_FLAG_STRIP_HIGH and FILTER_FLAG_STRIP_LOW, just call it like this:

$string = filter_var($string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_LOW);

The same goes for passing a flags field in an options array in the case of using callbacks.

$var = filter_var($string, FILTER_SANITIZE_SPECIAL_CHARS,
array('flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH));

Thanks to the Brain Goo blog at popmartian.com/tipsntricks/for this info.
Anonymous 22-Oct-2015 03:56
FILTER_SANITIZE_STRING doesn't behavior the same as strip_tags function.    strip_tags allows less than symbol inferred from context, FILTER_SANITIZE_STRING strips regardless.
<?php
$smaller
= "not a tag < 5";
echo
strip_tags($smaller);    // -> not a tag < 5
echo filter_var ( $smaller, FILTER_SANITIZE_STRING); // -> not a tag
?>
david dot drakulovski at gmail dot com 25-Feb-2014 07:54
Here is a simpler and a better presented ASCII list for the <32 or 127> filters
(if wikipedia confused the hell out of you):

http://www.danshort.com/ASCIImap/
galvao at galvao dot eti dot br 02-Mar-2013 06:04
Just to clarify, since this may be unknown for a lot of people:

ASCII characters above 127 are known as "Extended" and they represent characters such as greek letters and accented letters in latin alphabets, used in languages such as pt_BR.

A good ASCII quick reference (aside from the already mentioned Wikipedia article) can be found at: http://www.asciicodes.com/
Anonymous 15-Feb-2013 07:42
Support for FILTER_SANITIZE_FULL_SPECIAL_CHARS was added from version 5.3.3
googlybash24 at aol dot com 19-Sep-2012 05:39
Remember to trim() the $_POST before your filters are applied:

<?php

// We trim the $_POST data before any spaces get encoded to "%20"

// Trim array values using this function "trim_value"
function trim_value(&$value)
{
   
$value = trim($value);    // this removes whitespace and related characters from the beginning and end of the string
}
array_filter($_POST, 'trim_value');    // the data in $_POST is trimmed

$postfilter =    // set up the filters to be used with the trimmed post array
   
array(
           
'user_tasks'                        =>    array('filter' => FILTER_SANITIZE_STRING, 'flags' => !FILTER_FLAG_STRIP_LOW),    // removes tags. formatting code is encoded -- add nl2br() when displaying
           
'username'                            =>    array('filter' => FILTER_SANITIZE_ENCODED, 'flags' => FILTER_FLAG_STRIP_LOW),    // we are using this in the url
           
'mod_title'                            =>    array('filter' => FILTER_SANITIZE_ENCODED, 'flags' => FILTER_FLAG_STRIP_LOW),    // we are using this in the url
       
);

$revised_post_array = filter_var_array($_POST, $postfilter);    // must be referenced via a variable which is now an array that takes the place of $_POST[]
echo (nl2br($revised_post_array['user_tasks']));    //-- use nl2br() upon output like so, for the ['user_tasks'] array value so that the newlines are formatted, since this is our HTML <textarea> field and we want to maintain newlines
?>
googlybash24 at aol dot com 13-Sep-2012 08:39
This should help with most simple "textarea" fields in post forms.

Removing user html tags while maintaining text formatting such as newlines and carriage returns involves using the FILTER_SANITIZE_STRING filter ID with the flag !FILTER_FLAG_STRIP_LOW. The formatting text (the low ASCII values under decimal 32) are encoded because of the included FILTER_FLAG_ENCODE_LOW flag, but you are now preventing these from being removed. When you want to display the value on the page back in its intended format, use nl2br() so the encoded newlines are formatted properly on the page.

This example cleans $_POST data from a textarea field with the name "user_tasks" on a previous html form, stripping tags but maintaining formatting (at least for newlines):

<?php
$postfilter
=
    array(
           
'user_tasks'    =>    array('filter' => FILTER_SANITIZE_STRING, 'flags' => !FILTER_FLAG_STRIP_LOW),    // removes tags. formatting code is encoded -- add nl2br() when displaying
       
);

$revised_post_array = filter_input_array(INPUT_POST, $postfilter);    // must be referenced via a variable which is now an array that takes the place of $_POST[]
echo (nl2br($revised_post_array['user_tasks']));    // here we use nl2br() for the displayed value, for the ['user_tasks'] array value so that the newlines are formatted
?>
adellemfrank at hotmail dot com 09-Jul-2012 07:07
A good list of which ASCII characters are < 32 and > 127 can be found at: http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters
scamber256 at hotmail dot de 06-Aug-2011 02:37
Just a hint I tested,

You can obtain all the chars <32 (so newline and c.return), by using not operator > !FILTER_FLAG_STRIP_LOW as the last argument.

Example:
filter_input(INPUT_GET,'test',FILTER_SANITIZE_STRING,!FILTER_FLAG_STRIP_LOW);

The filter keeps working as before removing anything else as before apart from FILTER_FLAG_STRIP_LOW.
Just filter those "bad" chars <32 manually you don't want.
Dmitry Snytkine 11-Apr-2011 04:17
Beware that FILTER_FLAG_STRIP_LOW strips NEWLINE and TAG and CARRIAGE RETURN chars. If you have a form that accepts user input in plaintext format, all the submitted text will lose all the line breaks, making it appear all on one line. This basically renders this filter useless for parsing user-submitted text, even in plain text.
marcus at synchromedia dot co dot uk 27-Nov-2009 01:07
It's not entirely clear what the LOW and HIGH ranges are. LOW is characters below 32, HIGH is those above 127, i.e. outside the ASCII range.

<?php
$a
= "\tcafé\n";
//This will remove the tab and the line break
echo filter_var($a, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
//This will remove the é.
echo filter_var($a, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
?>