Filter 函数
在线手册:中文 英文
PHP手册

filter_var

(PHP 5 >= 5.2.0)

filter_varFilters a variable with a specified filter

说明

mixed filter_var ( mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]] )

参数

variable

Value to filter.

filter

The ID of the filter to apply. The Types of filters manual page lists the available filters.

options

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.

<?php
// 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);

// for filter that only accept flags, you can pass them directly
$var filter_var('oops'FILTER_VALIDATE_BOOLEANFILTER_NULL_ON_FAILURE);

// for filter 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(", "$value2);
    
$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'));
?>

返回值

Returns the filtered data, or FALSE if the filter fails.

范例

Example #1 A filter_var() example

<?php
var_dump
(filter_var('bob@example.com'FILTER_VALIDATE_EMAIL));
var_dump(filter_var('http://example.com'FILTER_VALIDATE_URLFILTER_FLAG_PATH_REQUIRED));
?>

以上例程会输出:

string(15) "bob@example.com"
bool(false)

参见


Filter 函数
在线手册:中文 英文
PHP手册
PHP手册 - N: Filters a variable with a specified filter

用户评论:

ole dot aass at yahoo dot no (10-Feb-2012 10:41)

Like mentioned by php at maisqi dot com, this function does not support IDN, and instead for reinventing the wheel we can use the idn_to_ascii function in the intl module.

Example:
<?php
function validateUrl($url)
{
   
$idn = idn_to_ascii($url);
    return
filter_var($idn, FILTER_VALIDATE_URL);
}
?>

How it works, is that idn_to_ascii converts the multi-byte url to a punycode ascii string. Below is the example in these docs

<?php
echo idn_to_ascii('t?st.de');
?>

Returns: xn--tst-qla.de

This is the actual url stored in the DNS

That string can also be reversed by using idn_to_utf8()

keevitaja at gmail dot com (29-Jan-2012 04:05)

please note FILTER_VALIDATE_URL passes following url

http://test.ee/sdsf"f

marc at nwd dot mx (17-Oct-2011 06:47)

Validating with no TLD is correct. If you have local servers and use it for local domain based emails (i.e. user@localhost) it's completely valid.

If you want to check for emails with TLD, you can either use a regular expression or some framework. I personally use Zend Framework's Zend_Validate_Email.

sampathperera at hotmail dot com (03-Aug-2011 06:36)

PHP FILTER_VALIDATE_EMAIL validates with no TLD

<?php
var_dump
(filter_var('bob@example', FILTER_VALIDATE_EMAIL));
?>

Output bool(false) expected.

But it returns: string(11) "bob@example"

joelhy (06-Jul-2011 10:44)

For those looking for private ip checking, there it is:
<?php
 
function is_private_ip($ip)
{
     return !
filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE);
}
?>

Luke America (05-Jun-2011 02:09)

And ... if you also want to handle pre-encoded multi-byte international URL's, you can include the additional code here:

<?php

// convert multi-byte international url's by stripping multi-byte chars
$uri = urldecode($uri) . ' ';
$len = mb_strlen($uri);
if (
$len !== strlen($uri))
{
       
$convmap = array(0x0, 0x2FFFF, 0, 0xFFFF);
       
$uri = mb_decode_numericentity($uri, $convmap, 'UTF-8');
}
$uri = trim($uri);

// now, process pre-encoded MBI's
$regex = '#&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);#i';
$uri_test = preg_replace($regex, '$1', htmlentities($uri, ENT_QUOTES, 'UTF-8'));
if (
$uri_test != '') {$uri = $uri_test;}

?>

php at maisqi dot com (27-May-2011 03:11)

FILTER_VALIDATE_URL does not support internationalized domain name (IDN). Valid or not, no domain name with Unicode chars on it will pass validation.

We can circumvent this with a home grown solutions, but C code is C code, so I've gone for the code bellow, which builds on filter_var().

<?php
$res
= filter_var ($uri, FILTER_VALIDATE_URL);
if (
$res) return $res;
// Check if it has unicode chars.
$l = mb_strlen ($uri);
if (
$l !== strlen ($uri)) {
   
// Replace wide chars by “X”.
   
$s = str_repeat (' ', $l);
    for (
$i = 0; $i < $l; ++$i) {
       
$ch = mb_substr ($uri, $i, 1);
       
$s [$i] = strlen ($ch) > 1 ? 'X' : $ch;
    }
   
// Re-check now.
   
$res = filter_var ($s, FILTER_VALIDATE_URL);
    if (
$res) {    $uri = $res; return 1;    }
}
?>

The logic is simple. A non-ascii char is more than one byte long. We replace every one of those chars by "X" and check again.

An alternative will be to punycode the URI before calling filter_var(), but PHP lacks native support for punycode. I think my approach is effective. Please e-mail me if you think otherwise or see room for improvement.

Arvid Bergelmir (11-Jan-2010 01:18)

This function will return FALSE on failure but be careful validating boolean values:

Validation failed:
<?php filter_var('abc', FILTER_VALIDATE_BOOLEAN); // bool(false) ?>

Validation correct:
<?php filter_var('0', FILTER_VALIDATE_BOOLEAN); // bool(false) ?>

drtebi at yahoo (25-Nov-2009 07:55)

Notice that filter_var with FILTER_VALIDATE_EMAIL does not work if you are trying to get a String from an XML document e.g. via xpath.

I often use XML files as configuration files and use a function that returns a string from the config file via xpath. While this worked fine before 5.2.11, it doesn't anymore (and shouldn't, since it's an XML Element, not a String).

To overcome this problem, $variable can be type-casted:

<?php
$variable
= fancyXmlGetFunction('from');
filter_var((String) $variable, FILTER_VALIDATE_EMAIL);
?>

suit dot 2009 at rebell dot at (07-Aug-2009 11:11)

If PHP >= 5.2 is not present, you can use the regular expression of the original PHP-c-file:

http://svn.php.net/viewvc/php/php-src/trunk/ext/filter/logical_filters.c

Instead of:
<?php filter_var('bob@example.com', FILTER_VALIDATE_EMAIL)); ?>

Just use preg_match(); with a copy of the original regular expression (found in the void "php_filter_validate_email") in logical_filters.c

in fact, this expression (and the original filter-funktion) ignores RFC 5321 (Section 4.5.3.1. Size Limits and Minimums).

tedivm at tedivm dot com (22-Jun-2009 09:28)

How to pass options and flags-

<?php
$options
= array();
$options['options']['min_range'] = 1;
$options['options']['max_range'] = 10;
$options['flags'] = FILTER_FLAG_ALLOW_OCTAL;
filter_var(3, FILTER_VALIDATE_INT, $options);
?>

Meska (30-Apr-2009 08:08)

Just a little filter to validate IP v4 & v6
This little script display result in function of the query
<?php
$ipv6
="2a01:e35:aaa4:6860:a5e7:5ba9:965e:cc93";
$ipv4="82.237.3.3";
$fake = "3342423423";
$ipv4priv = "255.255.255.255";
$ipv6priv = "::1";
echo
"<pre>";
echo
$ipv4;
echo
"<br />";
var_dump(filter_var($ipv4,FILTER_VALIDATE_IP));
echo
"<br />";
echo
$ipv6;
echo
"<br />";
var_dump(filter_var($ipv6,FILTER_VALIDATE_IP));
echo
"<br />";
echo
$fake;
echo
"<br />";
var_dump(filter_var($fake,FILTER_VALIDATE_IP));
echo
"<br />";
echo
$ipv4priv;
echo
"<br/>";
echo
"FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE";
echo
"<br />";
var_dump(filter_var($ipv4priv,FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE));
echo
"<br />";
echo
$ipv4priv;
echo
"<br/>";
echo
"FILTER_FLAG_NO_PRIV_RANGE";
echo
"<br />";
var_dump(filter_var($ipv4priv,FILTER_FLAG_NO_PRIV_RANGE));
echo
"<br />";
echo
$ipv6priv;
echo
"<br/>";
echo
"FILTER_FLAG_NO_PRIV_RANGE";
echo
"<br />";
var_dump(filter_var($ipv6priv,FILTER_FLAG_NO_PRIV_RANGE));
echo
"<br />";
echo
$ipv6priv;
echo
"<br />";
var_dump(filter_var($ipv6priv,FILTER_VALIDATE_IP));

echo
"</pre>";

?>

jon dot bertsch at ucop dot edu (24-Mar-2009 03:49)

Here's an actual example of the filter syntax with a flag since there doesn't appear to be a one liner for this anywhere:

'hours' => array('filter'=>FILTER_SANITIZE_NUMBER_FLOAT, 'flags' => FILTER_FLAG_ALLOW_FRACTION, 'options'=> '.')

dyer85 at gmail dot com (03-Nov-2008 10:00)

Note that when using FILTER_VALIDATE_INT along with the FILTER_FLAG_ALLOW_HEX flag, the string "2f", for example, is not validated successfully, because you must use the "0x" prefix, otherwise, it treats the data as base 10.

The range options are also smart enough to recognize when the boundaries are exceeded in different bases.

Here's an example:

<?php

$foo
= '256';
$bar = '0x100';
var_dump(validate_int($foo)); // false, too large
var_dump(validate_int($bar)); // false, too large

function validate_int($input)
{
  return
filter_var(
   
$input,
   
FILTER_VALIDATE_INT,

   
// We must pass an associative array
    // to include the range check options.
   
array(
     
'flags'   => FILTER_FLAG_ALLOW_HEX,
     
'options' => array('min_range' => 1, 'max_range' => 0xff)
    )
  );
}

?>

visseraj at gmail dot com (28-Aug-2008 06:31)

Here are the other possible flags that you can use:
http://us3.php.net/manual/hu/ref.filter.php

dale dot liszka at gmail dot com (09-Jul-2008 06:15)

Here is how to use multiple flags (for those who learn better by example, like me):

<?php
echo "|asdf".chr(9).chr(128)."_123|";
echo
"\n";
// "bitwise conjunction" means logic OR / bitwise |
echo filter_var("|asdf".chr(9).chr(128)."_123\n|" ,FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);

/*
Results:
|asdf    ?_123|
|asdf_123|
*/
?>

dale dot liszka at gmail dot com (09-Jul-2008 05:54)

Using the FILTER_CALLBACK requires an array to be passed as the options:

<?php
function toDash($x){
   return
str_replace("_","-",$x);
}

echo
filter_var("asdf_123",FILTER_CALLBACK,array("options"=>"toDash"));
// returns 'asdf-123'
?>

John (26-Jul-2007 08:35)

I managed to get this to work with PHP 5.1.6 on CentOS 5 with minor difficulty.

1) Download the PECL filter package
2) Extract the tarball
3) phpize the directory
4) ./configure
5) make
6) filter-0.11.0/logical_filters.c:25:31: error: ext/pcre/php_pcre.h: No such file or directory
7) find / -name php_pcre.h
8) Make sure php-devel is installed
9) Edit filter-0.11.0/logical_filters.c and replace "ext/pcre/php_pcre.h" with the absolute path of php_pcre.h
10) make
11) make install
12) add "extension=filter.so" to php.ini
13) Restart Apache