-
-
- /*
- 저작권 2009 Dominic Sayers
- (dominic_sayers@hotmail.com)
- (http://www.dominicsayers.com)
출처 파일에는 CPAL(Common Public Attribution License) 버전 1.0 라이선스가 적용됩니다.
- 라이센스 조건은 http://www.opensource.org/licenses/cpal_1.0의 월드와이드 웹을 통해 확인할 수 있습니다.
- */
- function is_email ($email, $checkDNS = false) {
- // $email이 유효한 주소인지 확인
- // (http://tools.ietf.org/html/rfc3696)
- // (http://tools.ietf.org/ html/rfc5322#section-3.4.1)
- // (http://tools.ietf.org/html/rfc5321#section-4.1.3)
- // (http://tools.ietf. org/html/rfc4291#section-2.2)
- // (http://tools.ietf.org/html/rfc1123#section-2.1)
-
- // 최신 이메일 주소는 "로컬"로 구성됩니다. "부분"은
- 에서 구분됩니다. // "도메인 부분"(정규화된 도메인 이름)은 at 기호("@")로 구분됩니다.
- // (http://tools.ietf.org/html/rfc3696#section-3)
- $index = strrpos($email,'@');
- < p> if ($index === false) false를 반환합니다. // at 기호 없음
- if ($index === 0) return false; // 로컬 부분 없음
- if ($index > 64) return false; // 로컬 부분이 너무 깁니다
$localPart = substr($email, 0, $index);
- $domain = substr($email, $index 1);
- $domainLength = strlen($domain);
-
- if ($domainLength === 0) 반환 false; // 도메인 부분 없음
- if ($domainLength > 255) return false; // 도메인 부분이 너무 깁니다
// 로컬 부분에서 RFC 준수 여부를 확인해 보겠습니다...
- //
- // 마침표(".")가 나타날 수 있지만...
- 을 시작하거나 끝내는 데 사용할 수는 없습니다. 부분적으로 나타나거나 두 개 이상의 연속된 마침표가 나타날 수 없습니다.
- // (http://tools.ietf.org/html/rfc3696#section-3)
- if (preg_match('/^\.|\.\.|\.$/', $localPart ) > 0) 거짓을 반환합니다. // 점이 잘못된 위치에 있습니다
//
- // at 기호("@"), 백슬래시, 큰따옴표, 쉼표 또는 대괄호 이외의 모든 ASCII 그래픽(인쇄) 문자는
- // 인용 없이 나타날 수 있습니다. 제외된 문자 목록
- //이 나타나면 따옴표로 묶어야 합니다.
- // (http://tools.ietf.org/html/rfc3696#section-3)
- if ( preg_match('/^"(?:.)*"$/', $localPart) > 0) {
- // 로컬 부분은 인용된 문자열입니다.
- if (preg_match('/(?:.) [^\\]"(?:.) /', $localPart) > 0) return false; // 인용된 문자열 내의 이스케이프 처리되지 않은 인용 문자
- } else {
- if (preg_match('/[ @\ [\]\\",]/', $localPart) > 0)
- // 제외된 모든 문자가 이스케이프되었는지 확인
- $stripped = preg_replace('/\\[ @\[\]\\" ,]/', '', $localPart)
- if (preg_match('/[ @\[\]\\",]/', $stripped) > 0) return false; // 따옴표가 없는 제외 문자
- }
// 이제 도메인 부분을 확인해 보겠습니다...
// 도메인 이름은 대괄호 안의 IP 주소로 대체할 수도 있습니다.
- // (http://tools.ietf.org/html/rfc3696#section-3)
- // (http:// tools.ietf.org/html/rfc5321#section-4.1.3)
- // (http://tools.ietf.org/html/rfc4291#section-2.2)
- if (preg_match('/^ \[(.) ]$/', $domain) === 1) {
- // 주소 리터럴입니다.
- $addressLiteral = substr($domain, 1, $domainLength - 2);
- $matchesIP = 배열();
-
- // 주소 리터럴 끝에서 IPv4 부분 추출(있는 경우)
- if (preg_match('/\b(?:(?:25[0-5]|2 [0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][ 0-9]|[01]?[0-9][0-9]?)$/', $addressLiteral, $matchesIP) > 0) {
- $index = strrpos($addressLiteral, $matchesIP[ 0]);
-
- if ($index === 0) {
- // 유효한 IPv4 주소 외에는 아무것도 없으므로...
- return true;
- }else {
- // 혼합 주소(IPv6 IPv4)에서 시도했다고 가정
- if ($addressLiteral[$index - 1] !== ':') return false; // IPv4 주소 앞의 문자는 ':'이어야 합니다.
- if (substr($addressLiteral, 0, 5) !== 'IPv6:') return false; // RFC5321 섹션 4.1.3
$IPv6 = substr($addressLiteral, 5, ($index ===7) ? 2 : $index - 6);
- $groupMax = 6;
- }
- } else {
- // 순수 IPv6에서의 시도여야 합니다.
- if (substr($addressLiteral, 0, 5) !== 'IPv6:') return false; // RFC5321 섹션 4.1.3
- $IPv6 = substr($addressLiteral, 5);
- $groupMax = 8;
- }
$groupCount = preg_match_all('/^[0-9a-fA-F]{0,4}|\:[0-9a-fA-F]{0,4}|(.)/', $IPv6, $ IP와 일치);
- $index = strpos($IPv6,'::');
if ($index === false) {
- // 정확한 수의 그룹이 필요합니다
- if ($groupCount !== $groupMax) return false; // RFC5321 섹션 4.1.3
- } else {
- if ($index !== strrpos($IPv6,'::')) return false; // 둘 이상의 '::'
- $groupMax = ($index === 0 || $index === (strlen($IPv6) - 2)) ? $groupMax : $groupMax - 1;
- if ($groupCount > $groupMax)는 false를 반환합니다. // 주소
- }
에 IPv6 그룹이 너무 많습니다. // 일치하지 않는 문자가 있는지 확인
- array_multisort($matchesIP[1], SORT_DESC);
- if ($matchesIP[1][0] !== '') 반환 false; // 주소
에 잘못된 문자가 있습니다. // 유효한 IPv6 주소이므로...
- return true;
- } else {
- // 도메인 이름입니다...
// 합법적인 인터넷 호스트 이름의 구문은 RFC-952에 지정되었습니다.
- // 이에 따라 호스트 이름 구문의 한 측면이 변경되었습니다.
- // 첫 번째 문자에 대한 제한이 완화되어
- // 문자 또는 숫자.
- // (http://tools.ietf.org/html/rfc1123#section-2.1)
- //
- // NB RFC 1123은 RFC 1035를 업데이트하지만 이는 현재 RFC를 읽어도 명확하지 않습니다. 1035.
- //
- // 이메일과 웹을 포함한 대부분의 일반적인 애플리케이션은 일반적으로...이스케이프된 문자열을 허용하지 않습니다.
- // (http://tools.ietf.org/html/rfc3696 #section-2)
- //
- // 알파벳 문자, 숫자, 하이픈 이외의 문자는 도메인 이름에 표시되어서는 안 됩니다.
- // SMTP 클라이언트 또는 서버 라벨
- // ( http://tools.ietf.org/html/rfc5321#section-4.1.2)
- //
- // RFC5321에서는 SMTP 목적으로 도메인 이름 뒤에 점을 사용하는 것을 금지합니다.
- // (http://tools.ietf.org/html/rfc5321#section-4.1.2)
- $matches = array();
- $groupCount = preg_match_all('/(?:[0-9a-zA-Z][0-9a-zA-Z-]{0,61}[0-9a-zA-Z]|[a- zA-Z])(?:\.|$)|(.)/', $domain, $matches);
- $level = count($matches[0]);
if ($level == 1) false를 반환합니다. // 메일 호스트는 TLD
일 수 없습니다. $TLD = $matches[0][$level - 1];
- if (substr($TLD, strlen($TLD) - 1, 1) === '.') return false; // TLD는 점으로 끝날 수 없습니다.
- if (preg_match('/^[0-9] $/', $TLD) > 0) return false; // TLD는 모두 숫자일 수 없습니다
// 일치하지 않는 문자가 있는지 확인
- array_multisort($matches[1], SORT_DESC);
- if ($matches[1][0] !== '') 반환 false; // 도메인에 잘못된 문자가 있거나 63자를 초과하는 라벨이 있습니다
// DNS를 확인하시겠습니까?
- if ($checkDNS && function_exists('checkdnsrr')) {
- if (!(checkdnsrr($domain, 'A') || checkdnsrr($domain, 'MX'))) {
- return 거짓; // 도메인이 실제로 존재하지 않습니다
- }
- }
// 다른 모든 요소를 제거하고 남는 것이 진실임에 틀림없다.
- // (Sherlock Holmes, The Sign of Four)
- return true;
- }
- }
function unitTest ($email, $reason = '') {
- $expected = ($reason === '') ? 사실 : 거짓;
- $valid = is_email($email);
- $not = ($valid) ? '' : ' 아니다';
- $예상치 못한 = ($valid !== $expected) ? ' 이건 예상치 못한 일이었습니다!' : '';
- $reason = ($reason === '') ? "" : " 이유: $reason";
-
- return "$email 주소는$유효하지 않습니다.$unexpected$reason
n";
- }
// 이메일 유효성 검사기 테스트 사례(Dominic Sayers, 2009년 1월)
- // 유효한 주소
- echo unitTest('first.last@example.com');
- echo unitTest('1234567890123456789012345678901234567890123456789012345678901234@example.com');
- echo unitTest('"first last"@example.com');
- echo unitTest('"first\"last"@example.com'); // 이것이 유효한지 확실하지 않습니다.
- echo unitTest('first\@last@example.com');
- echo unitTest('"first@last"@example.com');
- echo unitTest('first\\last@example.com') // 작은따옴표 문자열에서도 이스케이프됩니다. 이것은 테스트 중입니다 "first\last"@example.com
- echo unitTest('first.last@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23 456789.x23456789.x23456789.x23456789.x23456789 .
- x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x234 5');
- echo unitTest('first.last@[12.34.56.78]')
- echo unitTest('first.last@[IPv6:::12.34.56.78]')
- echo unitTest('first.last@[IPv6:1111:2222:3333::4444:12.34.56.78]' );
- echo 단위 테스트('first.last@[IPv6:1111:2222:3333:4444:5555:6666:12.34.56.78]')
- echo 단위 테스트('first.last@[IPv6:: :1111:2222:3333:4444:5555:6666]');
- echo unitTest('first.last@[IPv6:1111:2222:3333::4444:5555:6666]');
- echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666::]');
- echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888]');
- echo unitTest('first.last@x23456789012345678901234567890123456789012345678901234567890123.example.com');
- echo unitTest('first.last@1xample.com');
- echo unitTest('first.last@123.example.com');
// 잘못된 주소
- echo unitTest('first.last', "아니요 @ ");
- echo unitTest('@example.com', "로컬 부분 없음");
- echo unitTest('12345678901234567890123456789012345678901234567890123456789012345@example.com', "로컬 부분이 64자를 초과합니다.");
- echo unitTest('.first.last@example.com', "로컬 부분은 점으로 시작합니다.");
- echo unitTest('first.last.@example.com', "로컬 부분은 점으로 끝납니다.");
- echo unitTest('first..last@example.com', "로컬 부분에 연속된 점이 있습니다.");
- echo unitTest('"first"last"@example.com', "로컬 부분에 이스케이프 처리되지 않은 제외 문자가 포함되어 있습니다.");
- echo unitTest('first\\@last@example.com', "로컬 부분에 다음이 포함되어 있습니다." 이스케이프되지 않은 제외 문자");
- echo unitTest('first.last@', "도메인 없음");
- echo unitTest('first.last@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789. x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.
- x23456789.x23456789.x23456789.x23456789.x23456 789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456', "도메인이 255자를 초과합니다.");
- echo unitTest('first.last@[.12.34.56.78]', "IPv4 주소 앞에 올 수 있는 문자만 ':'입니다.")
- echo unitTest('first.last@[12.34.56.789] ', "IPv4로 해석할 수 없으므로 IPv6 태그가 없습니다.")
- echo unitTest('first.last@[::12.34.56.78]', "IPv6 태그가 없습니다.")
- echo unitTest('first.last@[IPv5:::12.34.56.78]', "IPv6 태그가 잘못되었습니다.")
- echo unitTest('first.last@[IPv6:1111:2222:3333::4444:5555 :12.34.56.78]', "IPv6 그룹이 너무 많습니다(최대 4개)");
- echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:12.34.56.78]', "IPv6 그룹이 충분하지 않습니다.");
- echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:12.34.56.78]', "IPv6 그룹이 너무 많습니다(최대 6개)");
- echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777]', "IPv6 그룹이 충분하지 않습니다.");
- echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888:9999]', "IPv6 그룹이 너무 많습니다(최대 8개)");
- echo unitTest('first.last@[IPv6:1111:2222::3333::4444:5555:6666]', "'::'이 너무 많습니다(없음 또는 1일 수 있음)");
- echo unitTest('first.last@[IPv6:1111:2222:3333::4444:5555:6666:7777]', "IPv6 그룹이 너무 많습니다(최대 6개)");
- echo unitTest('first.last@[IPv6:1111:2222:333x::4444:5555]', "x는 IPv6 주소에서 유효하지 않습니다.");
- echo unitTest('first.last@[IPv6:1111:2222:33333::4444:5555]', "33333은 IPv6 주소에서 유효한 그룹이 아닙니다.");
- echo unitTest('first.last@example.123', "TLD는 모두 숫자일 수 없습니다.");
- echo unitTest('first.last@com', "메일 호스트는 두 번째 이하 수준이어야 합니다.");
- echo unitTest('first.last@-xample.com', "레이블은 하이픈으로 시작할 수 없습니다.");
- echo unitTest('first.last@exampl-.com', "레이블은 하이픈으로 끝날 수 없습니다."); echo unitTest('Abc\@def@example.com');
- echo unitTest('Fred\ Bloggs@example.com');
- echo unitTest('Joe.\\Blow@example.com');
- echo unitTest('"Abc@def"@example.com');
- echo unitTest('"Fred Bloggs"@example.com');
- echo unitTest('user Mailbox@example.com');
- echo unitTest('customer/department=shipping@example.com');
- echo unitTest('$A12345@example.com');
- echo unitTest('!def!xyz�c@example.com');
- echo unitTest('_somename@example.com');
// Doug Lovell의 테스트 사례(LinuxJournal, 2007년 6월, http://www.linuxjournal.com/ 기사/9585)
- echo unitTest("dclo@us.ibm.com");
- echo unitTest("abc\@def@example.com");
- echo unitTest("abc\\@example.com");
- echo unitTest("Fred\ Bloggs@example.com");
- echo unitTest("Joe.\\Blow@example.com");
- echo unitTest(""Abc@def"@example.com");
- echo unitTest(""Fred Bloggs"@example.com");
- echo unitTest("customer/department=shipping@example.com");
- echo unitTest("$A12345@example.com");
- echo unitTest("!def!xyz�c@example.com");
- echo unitTest("_somename@example.com");
- echo unitTest("user Mailbox@example.com");
- echo unitTest("peter.piper@example.com");
- echo unitTest("Doug\ \"Ace\"\ Lovell@example.com");
- echo unitTest(""Doug \"Ace\" L."@example.com");
- echo unitTest("abc@def@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
- echo unitTest("abc\\@def@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
- echo unitTest("abc\@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
- echo unitTest("@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
- echo unitTest("doug@", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
- echo unitTest(""qu@example.com", "Doug Lovell이 이것이 실패해야 한다고 말합니다");
- echo unitTest("ote"@example.com", "Doug Lovell이 이것이 실패해야 한다고 말합니다");
- echo unitTest(".dot@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
- echo unitTest("dot.@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
- echo unitTest("two..dot@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
- echo unitTest(""Doug "Ace" L."@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
- echo unitTest("Doug\ \"Ace\"\ L\.@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
- echo unitTest("hello world@example.com", "Doug Lovell이 이것이 실패해야 한다고 말했습니다.");
- echo unitTest("gatsby@f.sc.ot.t.f.i.tzg.era.l.d.", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
- ?>
-
复代码
|