Keep in mind that FILTER_VALIDATE_EMAIL will validate the email address according to standards.
However, giving the fact that organizations are free to restrict the forms of their own email addresses, using ONLY this filter can you a lot of bounces.
gmail, yahoo, hotmail, aol have special rules
For example :
<?php
$email_a = '0hot\'mail_check@hotmail.com';
if (filter_var($email_a, FILTER_VALIDATE_EMAIL)) {
echo "This (email_a) email address is considered valid.";
//reported as valid
}
//there can be no "0hotmail_check@hotmail.com"
//because hotmail will say "Your email address needs to start with a letter. Please try again." even if you remove the '
?>
filter_var
(PHP 5 >= 5.2.0)
filter_var — Filtra una variable con el filtro que se indique
Descripción
Parámetros
-
variable -
Valor a filtrar
-
filter -
ID del filtro a usar. La página del manual Tipos de filtros lista los filtros disponibles.
-
options -
Array asociativo de opciones o disyunción lógica de flags. Si un filtro acepta opciones, se pueden indicar flags en el campo "flags" del array. Para el filtro "callback" debería pasarse el tipo callable. La llamada de la función de retorno (callback) debe aceptar un argumento, el valor a ser filtrado y debe retornar el valor tras su filtrado/saneamiento.
<?php
// Para filtros que acepten opciones, usar este formato
$opciones = array(
'options' => array(
'default' => 3, // valor a retornar si el filtro falla
// más opciones aquí
'min_range' => 0
),
'flags' => FILTER_FLAG_ALLOW_OCTAL,
);
$var = filter_var('0755', FILTER_VALIDATE_INT, $opciones);
// Para filtros que únicamente acepten flags, se pueden pasar directametne
$var = filter_var('oops', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
// Para filtros que únicamente acepten flags, también pueden pasarse como
// array
$var = filter_var('oops', FILTER_VALIDATE_BOOLEAN,
array('flags' => FILTER_NULL_ON_FAILURE));
// Filtro "callback2
function foo($value)
{
// Formato esperado: Apellido, Nombre
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'));
?>
Valores devueltos
Retorna los datos filtrados o FALSE si el filtro falla.
Ejemplos
Ejemplo #1 Un ejemplo de filter_var()
<?php
var_dump(filter_var('bob@example.com', FILTER_VALIDATE_EMAIL));
var_dump(filter_var('http://example.com', FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED));
?>
El resultado del ejemplo sería:
string(15) "bob@example.com" bool(false)
Ver también
- filter_var_array() - Retorna múltiple variables y opcionalmente las filtra
- filter_input() - Toma una variable externa concreta por nombre y opcionalmente la filtra
- filter_input_array() - Obtiene variables externas y opcionalmente las filtra
- Tipos de filtros
- información acerca de tipos de llamada de retorno
Pay attention that the function will not validate "not latin" domains.
if (filter_var('уникум@из.рф', FILTER_VALIDATE_EMAIL)) {
echo 'VALID';
} else {
echo 'NOT VALID';
}
please note FILTER_VALIDATE_URL passes following url
http://example.ee/sdsf"f
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
And this is also a valid url
http://example.com/"><script>alert(document.cookie)</script>
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.
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;}
?>
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'
?>
It's very likely that you actually want to detect all reserved ranges, not just private IPs, and there's another constant for them that should be bitwise-OR'd with it.
<?php
function is_private_ip($ip) {
return !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
}
?>
FILTER_SANITIZE_EMAIL header injection test.
<?php
$InjString = "\r\n|\n|%0A|%0D|bcc:|to:|cc:|Content-Type:|Mime-Type:|";
echo filter_var($InjString, FILTER_SANITIZE_EMAIL);
?>
||%0A|%0D|bcc|to|cc|Content-Type|Mime-Type|
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);
}
?>
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);
?>
Here are the other possible flags that you can use:
http://us3.php.net/manual/hu/ref.filter.php
One key thing to remember about filtering integers is that the value for the option max_range must be less than or equal to the value of PHP_INT_MAX.
filter_var($someVariable, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => SOME_VALUE_GREATER_THAN_PHP_INT_MAX)));
This will fail even if $someVariable is a valid integer in the expected range.
This can show up when you are attempting to validate a potential key for an unsigned MySQL INT type (whose maximum value is 4294967295) on a 32-bit system, where the value of PHP_INT_MAX is 2147483647.
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'=> '.')
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)
)
);
}
?>
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) ?>
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).
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|
*/
?>
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);
?>
