分享一个email验证类,代码如下:
<?php /** * EMail地址验证类 * 根据RFC5321,RFC5322,验证电子邮件地址 */ final class EmailAddressValidator { /** * 电子邮件地址验证 * * @access private * @var string $_emailAddress */ private $_emailAddress; /** * 是否允许带引号的字符串本地部分 * * @access private * @var bool $_quotedString */ private $_quotedString = false; /** * An obsolete local part * * @access private * @var bool $_obsolete */ private $_obsolete = false; /** * A domain literal domain * * @access private * @var bool $_domainLiteral */ private $_domainLiteral = false; /** * Comments and folding white spaces * * @access private * @var bool $_cfws */ private $_cfws = false; /** * Set the email address and turn on the relevant standard if required * * @access public * @param string $emailAddress * @param integer $standard */ public function __construct($emailAddress, $standard = null) { // Set the email address $this->_emailAddress = $emailAddress; // Turn on the RFC 5321 standard if requested if ($standard == 5321) { $this->setStandard5321(); } // Otherwise turn on the RFC 5322 standard if requested elseif ($standard == 5322) { $this->setStandard5322(); } } /** * Call the constructor fluently * * @access public * @static * @param string $emailAddress * @param null|integer $standard * @return EmailAddressValidator */ public static function setEmailAddress($emailAddress, $standard = null) { return new self($emailAddress, $standard); } /** * Validate the email address according to RFC 5321 and return itself * * @access public * @param bool $allow * @return EmailAddressValidator */ public function setStandard5321($allow = true) { // A quoted string local part is either allowed (true) or not (false) $this->_quotedString = $allow; // A domain literal domain is either allowed (true) or not (false) $this->_domainLiteral = $allow; // Return itself return $this; } /** * Validate the email address according to RFC 5322 and return itself * * @access public * @param bool $allow * @return EmailAddressValidator */ public function setStandard5322($allow = true) { // An obsolete local part is either allowed (true) or not (false) $this->_obsolete = $allow; // A domain literal domain is either allowed (true) or not (false) $this->_domainLiteral = $allow; // Comments and folding white spaces are either allowed (true) or not (false) $this->_cfws = $allow; // Return itself return $this; } /** * Either allow (true) or disallow (false) a quoted string local part and return itself * * @access public * @param bool $allow * @return EmailAddressValidator */ public function setQuotedString($allow = true) { // Either allow (true) or disallow (false) a quoted string local part $this->_quotedString = $allow; // Return itself return $this; } /** * Either allow (true) or disallow (false) an obsolete local part and return itself * * @access public * @param bool $allow * @return EmailAddressValidator */ public function setObsolete($allow = true) { // Either allow (true) or disallow (false) an obsolete local part $this->_obsolete = $allow; // Return itself return $this; } /** * Either allow (true) or disallow (false) a domain literal domain and return itself * * @access public * @param bool $allow * @return EmailAddressValidator */ public function setDomainLiteral($allow = true) { // Either allow (true) or disallow (false) a domain literal domain $this->_domainLiteral = $allow; // Return itself return $this; } /** * Either allow (true) or disallow (false) comments and folding white spaces and return itself * * @access public * @param bool $allow * @return EmailAddressValidator */ public function setCFWS($allow = true) { // Either allow (true) or disallow (false) comments and folding white spaces $this->_cfws = $allow; // Return itself 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-x08x0Bx0Cx0E-!#-[]-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 '([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>' . $this->_getCFWS() . '.' . $this->_getCFWS() . '(?2)){0,126}'; } /** * Return the regular expression for an IPv6 address * * @access private * @return string */ private function _getIPv6() { return '([a-f0-9]{1,4})(?>:(?3)){7}|(?!(?:.*[a-f0-9][:]]){8,})((?3)(?>:(?3)){0,6})?::(?4)?'; } /** * Return the regular expression for an IPv4-mapped IPv6 address * * @access private * @return string */ private function _getIPv6v4() { return '(?3)(?>:(?3)){5}:|(?!(?:.*[a-f0-9]:){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][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>.(?6)){3}'; } /** * Return the regular expression for a domain literal domain * * @access private * @return string */ private function _getDomainLiteral() { return '[(?:(?>IPv6:(?>' . $this->_getIPv6() . '))|(?>(?>IPv6:(?>' . $this->_getIPv6v4() . '))?' . $this->_getIPv4() . '))]'; } /** * Return either the regular expression for folding white spaces or its backreference if allowed * * @access private * @var bool $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>(?>[ ]+(?>x0Dx0A[ ]+)*)?)'; } } /** * Return the regular expression for comments * * @access private * @return string */ private function _getComments() { return '(?<comment>((?>' . $this->_getFWS() . '(?>[x01-x08x0Bx0Cx0E-'*-[]-x7F]|[x00-x7F]|(?P>comment)))*' . $this->_getFWS() . '))'; } /** * Return either the regular expression for comments and folding white spaces or its backreference if allowed * * @access private * @var bool $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(); } // Or the local part may be either a dot atom or a quoted string if the latter is allowed if ($this->_quotedString) { return '(?>' . $this->_getDotAtom() . '|' . $this->_getQuotedString() . ')'; } // Otherwise the local part may only 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 may be either a domain name or a domain literal if the latter is allowed if ($this->_domainLiteral) { return '(?>' . $this->_getDomainName() . '|' . $this->_getDomainLiteral() . ')'; } // Otherwise the domain must be a domain name return $this->_getDomainName(); } /** * Check to see if the domain can be resolved to MX RRs * * @access private * @param array $domain * @return bool */ private function _verifyDomain($domain) { // Return false if the domain cannot be resolved to MX RRs if (!checkdnsrr(end($domain), 'MX')) { return false; } // Otherwise return true return true; } /** * Perform the validation check on the email address's syntax and, if required, call _verifyDomain() * * @access public * @param bool $verify * @return bool|integer */ public function isValid($verify = false) { // Return false if the email address has an incorrect syntax if (!preg_match( '/^' . $this->_getCFWS() . $this->_getLocalPart() . $this->_getCFWS() . '@' . $this->_getCFWS() . $this->_getDomain() . $this->_getCFWS(true) . '$/isD' , $this->_emailAddress )) { return false; } // Otherwise check to see if the domain can be resolved to MX RRs if required if ($verify) { // Return 0 if the domain cannot be resolved to MX RRs if (!$this->_verifyDomain(explode('@', $this->_emailAddress))) { return 0; } // Otherwise return true return true; } // Otherwise return 1 return 1; } }
email验证类的调用示例:
<?php $valid = array( 1 => 'test@example.com', 2 => 'test@example.co.uk', 3 => 'test@example.museum', 4 => 'test@example', 5 => 'test@xn--example.com', 6 => 'test@example.xn--com', 7 => 'test.test@example.com', 8 => "!#$%&'*+-/=?^_`{|}~@example.com", 9 => 'test@123.com', 10 => 'test@example.123', 10 => 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl@example.com', 11 => 'test@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com', 11 => 'test@example.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk', 12 => 'a@a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.a.b.c.d.e.f.g.h.i.j.k.l .m.n.o.p.q.r.s.t.u.v.w.x.y.z.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v', 13 => '"test"@example.com', 14 => '"test@test"@example.com', 15 => '"test".test@example.com', 16 => 'test@[255.255.255.255]', 17 => 'test@[IPv6:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF]', 18 => 'test@[IPv6:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF::FFFF]', 19 => 'test@[IPv6:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255]', 20 => 'test@[IPv6:FFFF:FFFF:FFFF:FFFF:FFFF::255.255.255.255]', 21 => ' test @ example . com ', 22 => '(comment)test@example.com', 23 => '((nested)comment)test@example.com', 24 => 'test@(comment)[255.255.255.255]', 25 => '"My name".is."Michael" (and I am (really) awesome) @ ("That's what she said") example . com', ); $invalid = array( 1 => 'test', 2 => 'test@', 3 => '@example.com', 4 => 'test.@example.com', 5 => '.test@example.com', 6 => 'test..test@example.com', 7 => 'test@example..com', 8 => "tést@example.com", 9 => '"test@example.com', 10 => 'test"@example.com', 10 => '""@example.com', 11 => '"test"account"@example.com', 12 => 'a@a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.a.b.c.d.e.f.g.h.i.j .k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x', 13 => '"test"test@example.com', 14 => 'test@test@example.com', 15 => 'test@exam!ple.com', 16 => 'test@[255.255.255.256]', 17 => 'test@[IPv6:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF]', 18 => 'test@[IPv6:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF::FFFF:FFFF]', 19 => 'test@[IPv6:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255]', 20 => 'test@[IPv6:FFFF:FFFF:FFFF:FFFF:FFFF::FFFF:255.255.255.255]', 21 => 'test test@example.com', 22 => '(commenttest@example.com', 23 => '((nestedcomment)test@example.com', 24 => 'test@[255(comment).255.255.255]', 25 => ' @ ', ); include 'EmailAddressValidator.php'; foreach ($valid as $address) { if (!EmailAddressValidator::setEmailAddress($address, 5322)->isValid()) { echo 'Incorrect result: ' . $address . ' is a <strong>valid</strong> address.<br />'; } } foreach ($invalid as $address) { if (EmailAddressValidator::setEmailAddress($address, 5322)->isValid()) { echo 'Incorrect result: ' . $address . ' is an <strong>invalid</strong> address.<br />'; } }