3 * EmailAddressValidator Class
5 * @author Dave Child <dave@addedbytes.com>
6 * @link http://code.google.com/p/php-email-address-validation/
7 * @license http://www.opensource.org/licenses/bsd-license.php
9 class EmailAddressValidator
{
12 * Check email address validity
13 * @param strEmailAddress Email address to be checked
14 * @return True if email is valid, false if not
16 function check_email_address($strEmailAddress) {
18 // Control characters are not allowed
19 if (preg_match('/[\x00-\x1F\x7F-\xFF]/', $strEmailAddress)) {
23 // Split it into sections using last instance of "@"
24 $intAtSymbol = strrpos($strEmailAddress, '@');
25 if ($intAtSymbol === false) {
26 // No "@" symbol in email.
29 $arrEmailAddress[0] = substr($strEmailAddress, 0, $intAtSymbol);
30 $arrEmailAddress[1] = substr($strEmailAddress, $intAtSymbol +
1);
32 // Count the "@" symbols. Only one is allowed, except where
33 // contained in quote marks in the local part. Quickest way to
34 // check this is to remove anything in quotes.
35 $arrTempAddress[0] = preg_replace('/"[^"]+"/'
37 ,$arrEmailAddress[0]);
38 $arrTempAddress[1] = $arrEmailAddress[1];
39 $strTempAddress = $arrTempAddress[0] . $arrTempAddress[1];
40 // Then check - should be no "@" symbols.
41 if (strrpos($strTempAddress, '@') !== false) {
46 // Check local portion
47 if (!$this->check_local_portion($arrEmailAddress[0])) {
51 // Check domain portion
52 if (!$this->check_domain_portion($arrEmailAddress[1])) {
56 // If we're still here, all checks above passed. Email is valid.
62 * Checks email section before "@" symbol for validity
63 * @param strLocalPortion Text to be checked
64 * @return True if local portion is valid, false if not
66 function check_local_portion($strLocalPortion) {
67 // Local portion can only be from 1 to 64 characters, inclusive.
68 // Please note that servers are encouraged to accept longer local
69 // parts than 64 characters.
70 if (!$this->check_text_length($strLocalPortion, 1, 64)) {
73 // Local portion must be:
74 // 1) a dot-atom (strings separated by periods)
76 // 3) an obsolete format string (combination of the above)
77 $arrLocalPortion = explode('.', $strLocalPortion);
78 for ($i = 0, $max = sizeof($arrLocalPortion); $i < $max; $i++
) {
80 . '([A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]'
81 . '[A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]{0,63})'
85 ,$arrLocalPortion[$i])) {
93 * Checks email section after "@" symbol for validity
94 * @param strDomainPortion Text to be checked
95 * @return True if domain portion is valid, false if not
97 function check_domain_portion($strDomainPortion) {
98 // Total domain can only be from 1 to 255 characters, inclusive
99 if (!$this->check_text_length($strDomainPortion, 1, 255)) {
102 // Check if domain is IP, possibly enclosed in square brackets.
103 if (preg_match('/^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'
104 .'(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}$/'
105 ,$strDomainPortion) ||
106 preg_match('/^\[(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'
107 .'(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\]$/'
108 ,$strDomainPortion)) {
111 $arrDomainPortion = explode('.', $strDomainPortion);
112 if (sizeof($arrDomainPortion) < 2) {
113 return false; // Not enough parts to domain
115 for ($i = 0, $max = sizeof($arrDomainPortion); $i < $max; $i++
) {
116 // Each portion must be between 1 and 63 characters, inclusive
117 if (!$this->check_text_length($arrDomainPortion[$i], 1, 63)) {
120 if (!preg_match('/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|'
121 .'([A-Za-z0-9]+))$/', $arrDomainPortion[$i])) {
130 * Check given text length is between defined bounds
131 * @param strText Text to be checked
132 * @param intMinimum Minimum acceptable length
133 * @param intMaximum Maximum acceptable length
134 * @return True if string is within bounds (inclusive), false if not
136 function check_text_length($strText, $intMinimum, $intMaximum) {
137 // Minimum and maximum are both inclusive
138 $intTextLength = strlen($strText);
139 if (($intTextLength < $intMinimum) ||
($intTextLength > $intMaximum)) {