To be used in PHP versions which do not have the native function filter_var().
PHP Code:
/*
* Copyright © Michael Rushton 2009-10
* http://squiloople.com/
* Feel free to use and redistribute this code. But please keep this copyright notice.
*/
final class EmailAddressValidator {
private $email_address;
private $dot_atom = true;
private $strict_atom = true;
private $quoted_string = false;
private $obsolete_syntax = false;
private $domain_name = true;
private $strict_domain = true;
private $international = false;
private $domain_literal = false;
private function __construct($email_address, $strict) {
$this->email_address = $email_address;
if (!$strict) {
$this->SetStrict(false);
}
}
public static function SetEmailAddress($email_address, $strict = true) {
return new self($email_address, $strict);
}
public function SetStrict($strict = true) {
$this->SetStrictAtom($strict);
$this->SetQuotedString(!$strict);
$this->SetObsoleteSyntax(!$strict);
$this->SetStrictDomain($strict);
$this->SetInternational(!$strict);
$this->SetDomainLiteral(!$strict);
return $this;
}
public function SetDotAtom($allow = true) {
$this->dot_atom = $allow;
return $this;
}
public function SetStrictAtom($allow = true) {
$this->strict_atom = $allow;
return $this;
}
public function SetQuotedString($allow = true) {
$this->quoted_string = $allow;
return $this;
}
public function SetObsoleteSyntax($allow = true) {
$this->obsolete_syntax = $allow;
return $this;
}
public function SetDomainName($allow = true) {
$this->domain_name = $allow;
return $this;
}
public function SetStrictDomain($allow = true) {
$this->strict_domain = $allow;
return $this;
}
public function SetInternational($allow = true) {
$this->international = $allow;
return $this;
}
public function SetDomainLiteral($allow = true) {
$this->domain_literal = $allow;
return $this;
}
public function Validate() {
$atom = $this->strict_atom ? 'a-z0-9_-' : '\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E';
$dot_atom = '(?!.{65,}@)[' . $atom . ']+(?:\.[' . $atom . ']+)*';
$quoted_content = $this->obsolete_syntax ? '\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F' : '\x21\x23-\x5B\x5D-\x7E';
$quoted_pair = $this->obsolete_syntax ? '\x00-\x7F' : '\x09\x20-\x7E';
$quoted_string = '\x22(?:[' . $quoted_content . ']|(?:\x5C[' . $quoted_pair . '])){0,64}\x22';
$obsolete_syntax = '(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){65,}@)(?:(?:[' . $atom . ']+)|(?:' . $quoted_string . '))(?:\.(?:(?:[' . $atom . ']+)|(?:' . $quoted_string . ')))*';
$minimum = $this->strict_domain ? 1 : 0;
$international = $this->international ? '(?:xn--)?' : '';
$domain_name = '(?!.*[^.]{64,})(?:' . $international . '[a-z0-9]+(?:-[a-z0-9]+)*\.){' . $minimum . ',126}' . $international . '[a-z0-9]+(?:-[a-z0-9]+)*';
$ipv6_full = '[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7}';
$ipv6_comp = '(?!(?:.*[a-f0-9][:\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?';
$ipv6 = '(?:(?:' . $ipv6_full . ')|(?:' . $ipv6_comp . '))';
$ipv6v4_full = '[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:';
$ipv6v4_comp = '(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?';
$ipv6v4 = '(?:(?:' . $ipv6v4_full . ')|(?:' . $ipv6v4_comp . '))';
$ipv4 = '(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}';
$domain_literal = '\[(?:(?:IPv6:' . $ipv6 . ')|(?:(?:IPv6:' . $ipv6v4 . ')?' . $ipv4 . '))\]';
switch (true) {
case ($this->obsolete_syntax):
$local_part = $obsolete_syntax;
break;
case ($this->dot_atom && $this->quoted_string):
$local_part = '(?:(?:' . $dot_atom . ')|(?:' . $quoted_string . '))';
break;
case ($this->quoted_string):
$local_part = $quoted_string;
break;
default:
$local_part = $dot_atom;
}
switch (true) {
case ($this->domain_name && $this->domain_literal):
$domain = '(?:(?:' . $domain_name . ')|(?:' . $domain_literal . '))';
break;
case ($this->domain_literal):
$domain = $domain_literal;
break;
default:
$domain = $domain_name;
}
return preg_match('/^(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){255,})' . $local_part . '@' . $domain . '$/i', $this->email_address);
}
}
Examples:
PHP Code:
// Returns true
SetEmailAddress('michael@example.com')->Validate();
// Returns false
SetEmailAddress('"michael"@example.com')->Validate();
// Returns true
SetEmailAddress('"michael"@example.com')->SetQuotedString()->Validate();
// Returns true
SetEmailAddress('"michael"@[IPv6:FFFF:FFFF::255.255.255.255]', false)->Validate();
// Returns true
SetEmailAddress('"my".name."is".!!!@example.xn--fiqs8s')->SetObsoleteSyntax()->SetInternational()->Validate();
// Returns true
SetEmailAddress('a@b')->SetStrictDomain(false)->Validate();