PHP FILTER_VALIDATE_EMAIL does not work correctly
Validating e-mail adresses is kinda complicated.
Take a look at this list:
Valid email addresses
- niceandsimple@example.com
- very.common@example.com
- a.little.lengthy.but.fine@dept.example.com
- disposable.style.email.with+symbol@example.com
- user@[IPv6:2001:db8:1ff::a0b:dbd0]
- "much.more unusual"@example.com
- "very.unusual.@.unusual.com"@example.com
- "very.(),:;<>[]".VERY."very@\
"very".unusual"@strange.example.com - postbox@com (top-level domains are valid hostnames)
- admin@mailserver1 (local domain name with no TLD)
- !#$%&'*+-/=?^_`{}|~@example.org
- "()<>[]:,;@\"!#$%&'*+-/=?^_`{}| ~.a"@example.org
- " "@example.org (space between the quotes)
- üñîçøðé@example.com (Unicode characters in local part)
Invalid email addresses
- Abc.example.com (an @ character must separate the local and domain
parts) - A@b@c@example.com (only one @ is allowed outside quotation marks)
- a"b(c)d,e:f;gi[j\k]l@example.com (none of the special characters
in this local part are allowed outside quotation marks) - just"not"right@example.com (quoted strings must be dot separated, or
the only element making up the local-part) - this is"not\allowed@example.com (spaces, quotes, and backslashes may
only exist when within quoted strings and preceded by a backslash) - this\ still"not\allowed@example.com (even if escaped (preceded by
a backslash), spaces, quotes, and backslashes must still be
contained by quotes)
Source http://en.wikipedia.org/wiki/Email_address
Allmost all e-mail validation implementations are "bugged" but the php implementation is fine to work with because it accepts all common e-mail adresses
UPDATE:
Found on http://www.php.net/manual/en/filter.filters.validate.php
Regarding "partial" addresses with no . in the domain part, a comment in the source code (in ext/filter/logical_filters.c) justifies this rejection thus:
* The regex below is based on a regex by Michael Rushton.
* However, it is not identical. I changed it to only consider routeable
* addresses as valid. Michael's regex considers a@b a valid address
* which conflicts with section 2.3.5 of RFC 5321 which states that:
*
* Only resolvable, fully-qualified domain names (FQDNs) are permitted
* when domain names are used in SMTP. In other words, names that can
* be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed
* in Section 5) are permitted, as are CNAME RRs whose targets can be
* resolved, in turn, to MX or address RRs. Local nicknames or
* unqualified names MUST NOT be used.
And here is a link to the class from Michael Rushton (link broken see source below)
Which supports both RFC 5321/5322
<?php
/**
* Squiloople Framework
*
* LICENSE: Feel free to use and redistribute this code.
*
* @author Michael Rushton <michael@squiloople.com>
* @link http://squiloople.com/
* @package Squiloople
* @version 1.0
* @copyright © 2012 Michael Rushton
*/
/**
* Email Address Validator
*
* Validate email addresses according to the relevant standards
*/
final class EmailAddressValidator
{
// The RFC 5321 constant
const RFC_5321 = 5321;
// The RFC 5322 constant
const RFC_5322 = 5322;
/**
* The email address
*
* @access private
* @var string $_email_address
*/
private $_email_address;
/**
* A quoted string local part is either allowed (true) or not (false)
*
* @access private
* @var boolean $_quoted_string
*/
private $_quoted_string = FALSE;
/**
* An obsolete local part is either allowed (true) or not (false)
*
* @access private
* @var boolean $_obsolete
*/
private $_obsolete = FALSE;
/**
* A basic domain name is either required (true) or not (false)
*
* @access private
* @var boolean $_basic_domain_name
*/
private $_basic_domain_name = TRUE;
/**
* A domain literal domain is either allowed (true) or not (false)
*
* @access private
* @var boolean $_domain_literal
*/
private $_domain_literal = FALSE;
/**
* Comments and folding white spaces are either allowed (true) or not (false)
*
* @access private
* @var boolean $_cfws
*/
private $_cfws = FALSE;
/**
* Set the email address and turn on the relevant standard if required
*
* @access public
* @param string $email_address
* @param null|integer $standard
*/
public function __construct($email_address, $standard = NULL)
{
// Set the email address
$this->_email_address = $email_address;
// Set the relevant standard or throw an exception if an unknown is requested
switch ($standard)
{
// Do nothing if no standard requested
case NULL:
break;
// Otherwise if RFC 5321 requested
case self::RFC_5321:
$this->setStandard5321();
break;
// Otherwise if RFC 5322 requested
case self::RFC_5322:
$this->setStandard5322();
break;
// Otherwise throw an exception
default:
throw new Exception('Unknown RFC standard for email address validation.');
}
}
/**
* Call the constructor fluently
*
* @access public
* @static
* @param string $email_address
* @param null|integer $standard
* @return EmailAddressValidator
*/
public static function setEmailAddress($email_address, $standard = NULL)
{
return new self($email_address, $standard);
}
/**
* Validate the email address using a basic standard
*
* @access public
* @return EmailAddressValidator
*/
public function setStandardBasic()
{
// A quoted string local part is not allowed
$this->_quoted_string = FALSE;
// An obsolete local part is not allowed
$this->_obsolete = FALSE;
// A basic domain name is required
$this->_basic_domain_name = TRUE;
// A domain literal domain is not allowed
$this->_domain_literal = FALSE;
// Comments and folding white spaces are not allowed
$this->_cfws = FALSE;
// Return the EmailAddressValidator object
return $this;
}
/**
* Validate the email address using RFC 5321
*
* @access public
* @return EmailAddressValidator
*/
public function setStandard5321()
{
// A quoted string local part is allowed
$this->_quoted_string = TRUE;
// An obsolete local part is not allowed
$this->_obsolete = FALSE;
// Only a basic domain name is not required
$this->_basic_domain_name = FALSE;
// A domain literal domain is allowed
$this->_domain_literal = TRUE;
// Comments and folding white spaces are not allowed
$this->_cfws = FALSE;
// Return the EmailAddressValidator object
return $this;
}
/**
* Validate the email address using RFC 5322
*
* @access public
* @return EmailAddressValidator
*/
public function setStandard5322()
{
// A quoted string local part is disallowed
$this->_quoted_string = FALSE;
// An obsolete local part is allowed
$this->_obsolete = TRUE;
// Only a basic domain name is not required
$this->_basic_domain_name = FALSE;
// A domain literal domain is allowed
$this->_domain_literal = TRUE;
// Comments and folding white spaces are allowed
$this->_cfws = TRUE;
// Return the EmailAddressValidator object
return $this;
}
/**
* Either allow (true) or do not allow (false) a quoted string local part
*
* @access public
* @param boolean $allow
* @return EmailAddressValidator
*/
public function setQuotedString($allow = TRUE)
{
// Either allow (true) or do not allow (false) a quoted string local part
$this->_quoted_string = $allow;
// Return the EmailAddressValidator object
return $this;
}
/**
* Either allow (true) or do not allow (false) an obsolete local part
*
* @access public
* @param boolean $allow
* @return EmailAddressValidator
*/
public function setObsolete($allow = TRUE)
{
// Either allow (true) or do not allow (false) an obsolete local part
$this->_obsolete = $allow;
// Return the EmailAddressValidator object
return $this;
}
/**
* Either require (true) or do not require (false) a basic domain name
*
* @access public
* @param boolean $allow
* @return EmailAddressValidator
*/
public function setBasicDomainName($allow = TRUE)
{
// Either require (true) or do not require (false) a basic domain name
$this->_basic_domain_name = $allow;
// Return the EmailAddressValidator object
return $this;
}
/**
* Either allow (true) or do not allow (false) a domain literal domain
*
* @access public
* @param boolean $allow
* @return EmailAddressValidator
*/
public function setDomainLiteral($allow = TRUE)
{
// Either allow (true) or do not allow (false) a domain literal domain
$this->_domain_literal = $allow;
// Return the EmailAddressValidator object
return $this;
}
/**
* Either allow (true) or do not allow (false) comments and folding white spaces
*
* @access public
* @param boolean $allow
* @return EmailAddressValidator
*/
public function setCFWS($allow = TRUE)
{
// Either allow (true) or do not allow (false) comments and folding white spaces
$this->_cfws = $allow;
// Return the EmailAddressValidator object
return $this;
}
/**
* Return the regular expression for a dot atom local part
*
* @access private
* @return string
*/
private function _getDotAtom()
{
return "([!#-'*+\/-9=?^-~-]+)(?>\.(?1))*";
}
/**
* Return the regular expression for a quoted string local part
*
* @access private
* @return string
*/
private function _getQuotedString()
{
return '"(?>[ !#-\[\]-~]|\\\[ -~])*"';
}
/**
* Return the regular expression for an obsolete local part
*
* @access private
* @return string
*/
private function _getObsolete()
{
return '([!#-\'*+\/-9=?^-~-]+|"(?>'
. $this->_getFWS()
. '(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*'
. $this->_getFWS()
. '")(?>'
. $this->_getCFWS()
. '\.'
. $this->_getCFWS()
. '(?1))*';
}
/**
* Return the regular expression for a domain name domain
*
* @access private
* @return string
*/
private function _getDomainName()
{
// Return the basic domain name format if required
if ($this->_basic_domain_name)
{
return '(?>' . $this->_getDomainNameLengthLimit()
. '[a-z\d](?>[a-z\d-]*[a-z\d])?'
. $this->_getCFWS()
. '\.'
. $this->_getCFWS()
. '){1,126}[a-z]{2,6}';
}
// Otherwise return the full domain name format
return $this->_getDomainNameLengthLimit()
. '([a-z\d](?>[a-z\d-]*[a-z\d])?)(?>'
. $this->_getCFWS()
. '\.'
. $this->_getDomainNameLengthLimit()
. $this->_getCFWS()
. '(?2)){0,126}';
}
/**
* Return the regular expression for an IPv6 address
*
* @access private
* @return string
*/
private function _getIPv6()
{
return '([a-f\d]{1,4})(?>:(?3)){7}|(?!(?:.*[a-f\d][:\]]){8,})((?3)(?>:(?3)){0,6})?::(?4)?';
}
/**
* Return the regular expression for an IPv4-mapped IPv6 address
*
* @access private
* @return string
*/
private function _getIPv4MappedIPv6()
{
return '(?3)(?>:(?3)){5}:|(?!(?:.*[a-f\d]:){6,})(?5)?::(?>((?3)(?>:(?3)){0,4}):)?';
}
/**
* Return the regular expression for an IPv4 address
*
* @access private
* @return string
*/
private function _getIPv4()
{
return '(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(?>\.(?6)){3}';
}
/**
* Return the regular expression for a domain literal domain
*
* @access private
* @return string
*/
private function _getDomainLiteral()
{
return '\[(?:(?>IPv6:(?>'
. $this->_getIPv6()
. '))|(?>(?>IPv6:(?>'
. $this->_getIPv4MappedIPv6()
. '))?'
. $this->_getIPv4()
. '))\]';
}
/**
* Return either the regular expression for folding white spaces or its backreference
*
* @access private
* @param boolean $define
* @return string
*/
private function _getFWS($define = FALSE)
{
// Return the backreference if $define is set to FALSE otherwise return the regular expression
if ($this->_cfws)
{
return !$define ? '(?P>fws)' : '(?<fws>(?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)';
}
}
/**
* Return the regular expression for comments
*
* @access private
* @return string
*/
private function _getComments()
{
return '(?<comment>\((?>'
. $this->_getFWS()
. '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?P>comment)))*'
. $this->_getFWS()
. '\))';
}
/**
* Return either the regular expression for comments and folding white spaces or its backreference
*
* @access private
* @param boolean $define
* @return string
*/
private function _getCFWS($define = FALSE)
{
// Return the backreference if $define is set to FALSE
if ($this->_cfws && !$define)
{
return '(?P>cfws)';
}
// Otherwise return the regular expression
if ($this->_cfws)
{
return '(?<cfws>(?>(?>(?>'
. $this->_getFWS(TRUE)
. $this->_getComments()
. ')+'
. $this->_getFWS()
. ')|'
. $this->_getFWS()
. ')?)';
}
}
/**
* Establish and return the valid format for the local part
*
* @access private
* @return string
*/
private function _getLocalPart()
{
// The local part may be obsolete if allowed
if ($this->_obsolete)
{
return $this->_getObsolete();
}
// Otherwise the local part must be either a dot atom or a quoted string if the latter is allowed
if ($this->_quoted_string)
{
return '(?>' . $this->_getDotAtom() . '|' . $this->_getQuotedString() . ')';
}
// Otherwise the local part must be a dot atom
return $this->_getDotAtom();
}
/**
* Establish and return the valid format for the domain
*
* @access private
* @return string
*/
private function _getDomain()
{
// The domain must be either a domain name or a domain literal if the latter is allowed
if ($this->_domain_literal)
{
return '(?>' . $this->_getDomainName() . '|' . $this->_getDomainLiteral() . ')';
}
// Otherwise the domain must be a domain name
return $this->_getDomainName();
}
/**
* Return the email address length limit
*
* @access private
* @return string
*/
private function _getEmailAddressLengthLimit()
{
return '(?!(?>' . $this->_getCFWS() . '"?(?>\\\[ -~]|[^"])"?' . $this->_getCFWS() . '){255,})';
}
/**
* Return the local part length limit
*
* @access private
* @return string
*/
private function _getLocalPartLengthLimit()
{
return '(?!(?>' . $this->_getCFWS() . '"?(?>\\\[ -~]|[^"])"?' . $this->_getCFWS() . '){65,}@)';
}
/**
* Establish and return the domain name length limit
*
* @access private
* @return string
*/
private function _getDomainNameLengthLimit()
{
return '(?!' . $this->_getCFWS() . '[a-z\d-]{64,})';
}
/**
* Check to see if the domain can be resolved to MX RRs
*
* @access private
* @param array $domain
* @return integer|boolean
*/
private function _verifyDomain($domain)
{
// Return 0 if the domain cannot be resolved to MX RRs
if (!checkdnsrr(end($domain), 'MX'))
{
return 0;
}
// Otherwise return true
return TRUE;
}
/**
* Perform the validation check on the email address's syntax and, if required, call _verifyDomain()
*
* @access public
* @param boolean $verify
* @return boolean|integer
*/
public function isValid($verify = FALSE)
{
// Return false if the email address has an incorrect syntax
if (!preg_match(
'/^'
. $this->_getEmailAddressLengthLimit()
. $this->_getLocalPartLengthLimit()
. $this->_getCFWS()
. $this->_getLocalPart()
. $this->_getCFWS()
. '@'
. $this->_getCFWS()
. $this->_getDomain()
. $this->_getCFWS(TRUE)
. '$/isD'
, $this->_email_address
))
{
return FALSE;
}
// Otherwise check to see if the domain can be resolved to MX RRs if required
if ($verify)
{
return $this->_verifyDomain(explode('@', $this->_email_address));
}
// Otherwise return 1
return 1;
}
}
filter_var($email, FILTER_VALIDATE_EMAIL) not working in if condition
it seems that you don't check if $email
is set before validating the email. as an empty string or null
is not a valid email, the test fails and the message invalid email
is displayed
You should use this :
if(!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$emailErr = "Invalid email.";
echo $emailErr;
}
FILTER_VALIDATE_EMAIL not working
Change the first email check:
if ($email == "") {
print "email not there";
}
It is getting the value "
instead of checking for it.
php email validation (filter_validate_email) Not Working
check this code for email validation etc :
<body> <?php
// define variables and set to empty values
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["Name"])) {$nameErr = "Name is required"; }else {$Name = htmlspecialchars($_POST["Name"]);}
if (empty($_POST["Address"])) {$Address = "";}else{$Address = htmlspecialchars($_POST["Address"]);}
if (empty($_POST["Phone"])) {$Phone = "";}else {$Phone = htmlspecialchars($_POST["Phone"]);}
if (empty($_POST["Mobile"])) {$Mobile = "";}else {$Mobile = htmlspecialchars($_POST["Mobile"]);}
if(filter_var($_POST['Email'], FILTER_VALIDATE_EMAIL)){ echo"Valid Email"; }else{ echo "Not a Valid Email"; }
}
?>
<form name="addcontact" method="post" action= "<?php echo $_SERVER["PHP_SELF"];?>">
<table border="1" cellpadding="2"> <caption> Add New Caption </caption> <tr> <td><label for="Name">Name</label></td> <td><input type="text" name="Name" size="30" maxlenght="50" tabindex="1"/> <span class="error">*<?php echo $nameErr;?></span> </td> </tr>
<tr> <td><label for="Address">Address</label></td> <td><textarea name="Address" cols="45" rows="5" tabindex="2"></textarea></td> </tr>
<tr> <td><label for="Phone">Phone</label></td> <td><input type="text" name="Phone" size="20" maxlenght="20" tabindex="3" /> </td> </tr>
<tr> <td><label for="Mobile">Mobile</label></td> <td><input type="text" name="Mobile" size="20" maxlenght="20" tabindex="4" /> </td> </tr> <tr> <td><label for="Email">Email</label></td> <td><input type="text" name="Email" size="30" maxlenght="50" tabindex="5" /></td> </tr> <tr> <td colspan"2" align="center"><input type="Submit" name="Submit" value="Submit" tabindex="6"/> </td> </tr> </table> </form>
</body> </html>`
FILTER_VALIDATE_EMAIL saying a valid email is invalid
So, to not leave this question answer-less:
In your HTML code, you actually had <form action="" method="post" id="myform">
in both pages – but in your second page, you had another <form>
tag right before it … and because of this invalid HTML, the browser ignored the second form tag, and that made $("#myform").serialize()
not return any data at all, because it could not find the form element with that id.
You should always validate your HTML code. This helps avoiding such errors.
Not sure How to fix this issues about FILTER_VALIDATE_EMAIL
You want to use elseif for this, it will only trigger if the first condition isn't matched.
if ($email == NULL) {
$error['email'] = "email is missing";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error['emailfilter'] = "email is Invalid";
}
This will check the first condition, do they have an email, if not it'll populate $error['email']
, if the email has a value then it'll perform the filter_var
on the email to check it's validity.
FILTER_VALIDATE_EMAIL
The filter_var flag FILTER_VALIDATE_EMAIL
will do what it says = Validate value as e-mail, meaning if its not an email it will return false.
You might be looking for FILTER_SANITIZE_EMAIL
which will (Remove all characters, except letters, digits and !#$%&'*+-/=?^_`{|}~@.[] )
orFILTER_SANITIZE_STRING
will Strip tags, optionally strip or encode special characters.
Tho I don't recommend w3schools it has a list of filter_var flags http://www.w3schools.com/php/php_ref_filter.asp
Also as others have said, use PDO's prepared query's tobe safe, you can find a great pdo example here: http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html#10 which will explain a few things and there is also a simple pdo CRUD (Create Retrieve Update Delete) class here: http://www.phpro.org/classes/PDO-CRUD.html
good luck...
Does PHP's filter_var FILTER_VALIDATE_EMAIL actually work?
The regular expression used in the PHP 5.3.3 filter code is based on Michael Rushton's blog about Email Address Validation. It does seem to work for the case you mention.
You could also check out some of the options in Comparing E-mail Address Validating Regular Expressions (the regexp currently used in PHP is one of those tested).
Then you could choose a regexp you like better, and use it in a call to preg_match()
.
Or else you could take the regexp and replace the one in file PHP/ext/filter/logical_filter.c, function php_filter_validate_email()
, and rebuild PHP.
Related Topics
Creating a Soap Call Using PHP with an Xml Body
PHP "Pretty Print" JSON_Encode
How to Always Use Ignore-Platform-Reqs Flag When Running Composer
How to Load a PHP File into a Variable
How to Validate on Max File Size in Laravel
Converting Named HTML Entities to Numeric HTML Entities
Changing the Add to Cart Button Text in Woocommerce for Items with Variations
Natural Sorting Algorithm in PHP with Support for Unicode
Printing to Pos Printer from PHP
Aws Sdk for PHP: Error Retrieving Credentials from the Instance Profile Metadata Server
PHP $Stmt->Num_Rows Doesnt Work by Prepared Statements
In Laravel How to Add Values to a Request Array