PHP는 RFC 호환 이메일 주소 확인을 구현합니다.

WBOY
풀어 주다: 2016-07-25 08:56:42
원래의
1438명이 탐색했습니다.
  1. /*

  2. 저작권 2009 Dominic Sayers
  3. (dominic_sayers@hotmail.com)
  4. (http://www.dominicsayers.com)

  5. 출처 파일에는 CPAL(Common Public Attribution License) 버전 1.0 라이선스가 적용됩니다.

  6. 라이센스 조건은 http://www.opensource.org/licenses/cpal_1.0의 월드와이드 웹을 통해 확인할 수 있습니다.
  7. */
  8. function is_email ($email, $checkDNS = false) {
  9. // $email이 유효한 주소인지 확인
  10. // (http://tools.ietf.org/html/rfc3696)
  11. // (http://tools.ietf.org/ html/rfc5322#section-3.4.1)
  12. // (http://tools.ietf.org/html/rfc5321#section-4.1.3)
  13. // (http://tools.ietf. org/html/rfc4291#section-2.2)
  14. // (http://tools.ietf.org/html/rfc1123#section-2.1)
  15. // 최신 이메일 주소는 "로컬"로 구성됩니다. "부분"은
  16. 에서 구분됩니다. // "도메인 부분"(정규화된 도메인 이름)은 at 기호("@")로 구분됩니다.
  17. // (http://tools.ietf.org/html/rfc3696#section-3)
  18. $index = strrpos($email,'@');

  19. < p> if ($index === false) false를 반환합니다. // at 기호 없음
  20. if ($index === 0) return false; // 로컬 부분 없음
  21. if ($index > 64) return false; // 로컬 부분이 너무 깁니다

  22. $localPart = substr($email, 0, $index);

  23. $domain = substr($email, $index 1);
  24. $domainLength = strlen($domain);
  25. if ($domainLength === 0) 반환 false; // 도메인 부분 없음
  26. if ($domainLength > 255) return false; // 도메인 부분이 너무 깁니다

  27. // 로컬 부분에서 RFC 준수 여부를 확인해 보겠습니다...

  28. //
  29. // 마침표(".")가 나타날 수 있지만...
  30. 을 시작하거나 끝내는 데 사용할 수는 없습니다. 부분적으로 나타나거나 두 개 이상의 연속된 마침표가 나타날 수 없습니다.
  31. // (http://tools.ietf.org/html/rfc3696#section-3)
  32. if (preg_match('/^\.|\.\.|\.$/', $localPart ) > 0) 거짓을 반환합니다. // 점이 잘못된 위치에 있습니다

  33. //

  34. // at 기호("@"), 백슬래시, 큰따옴표, 쉼표 또는 대괄호 이외의 모든 ASCII 그래픽(인쇄) 문자는
  35. // 인용 없이 나타날 수 있습니다. 제외된 문자 목록
  36. //이 나타나면 따옴표로 묶어야 합니다.
  37. // (http://tools.ietf.org/html/rfc3696#section-3)
  38. if ( preg_match('/^"(?:.)*"$/', $localPart) > 0) {
  39. // 로컬 부분은 인용된 문자열입니다.
  40. if (preg_match('/(?:.) [^\\]"(?:.) /', $localPart) > 0) return false; // 인용된 문자열 내의 이스케이프 처리되지 않은 인용 문자
  41. } else {
  42. if (preg_match('/[ @\ [\]\\",]/', $localPart) > 0)
  43. // 제외된 모든 문자가 이스케이프되었는지 확인
  44. $stripped = preg_replace('/\\[ @\[\]\\" ,]/', '', $localPart)
  45. if (preg_match('/[ @\[\]\\",]/', $stripped) > 0) return false; // 따옴표가 없는 제외 문자
  46. }

  47. // 이제 도메인 부분을 확인해 보겠습니다...

  48. // 도메인 이름은 대괄호 안의 IP 주소로 대체할 수도 있습니다.

  49. // (http://tools.ietf.org/html/rfc3696#section-3)
  50. // (http:// tools.ietf.org/html/rfc5321#section-4.1.3)
  51. // (http://tools.ietf.org/html/rfc4291#section-2.2)
  52. if (preg_match('/^ \[(.) ]$/', $domain) === 1) {
  53. // 주소 리터럴입니다.
  54. $addressLiteral = substr($domain, 1, $domainLength - 2);
  55. $matchesIP = 배열();
  56. // 주소 리터럴 끝에서 IPv4 부분 추출(있는 경우)
  57. 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) {
  58. $index = strrpos($addressLiteral, $matchesIP[ 0]);
  59. if ($index === 0) {
  60. // 유효한 IPv4 주소 외에는 아무것도 없으므로...
  61. return true;
  62. }else {
  63. // 혼합 주소(IPv6 IPv4)에서 시도했다고 가정
  64. if ($addressLiteral[$index - 1] !== ':') return false; // IPv4 주소 앞의 문자는 ':'이어야 합니다.
  65. if (substr($addressLiteral, 0, 5) !== 'IPv6:') return false; // RFC5321 섹션 4.1.3

  66. $IPv6 = substr($addressLiteral, 5, ($index ===7) ? 2 : $index - 6);

  67. $groupMax = 6;
  68. }
  69. } else {
  70. // 순수 IPv6에서의 시도여야 합니다.
  71. if (substr($addressLiteral, 0, 5) !== 'IPv6:') return false; // RFC5321 섹션 4.1.3
  72. $IPv6 = substr($addressLiteral, 5);
  73. $groupMax = 8;
  74. }

  75. $groupCount = preg_match_all('/^[0-9a-fA-F]{0,4}|\:[0-9a-fA-F]{0,4}|(.)/', $IPv6, $ IP와 일치);

  76. $index = strpos($IPv6,'::');

  77. if ($index === false) {

  78. // 정확한 수의 그룹이 필요합니다
  79. if ($groupCount !== $groupMax) return false; // RFC5321 섹션 4.1.3
  80. } else {
  81. if ($index !== strrpos($IPv6,'::')) return false; // 둘 이상의 '::'
  82. $groupMax = ($index === 0 || $index === (strlen($IPv6) - 2)) ? $groupMax : $groupMax - 1;
  83. if ($groupCount > $groupMax)는 false를 반환합니다. // 주소
  84. }

  85. 에 IPv6 그룹이 너무 많습니다. // 일치하지 않는 문자가 있는지 확인

  86. array_multisort($matchesIP[1], SORT_DESC);
  87. if ($matchesIP[1][0] !== '') 반환 false; // 주소

  88. 에 잘못된 문자가 있습니다. // 유효한 IPv6 주소이므로...

  89. return true;
  90. } else {
  91. // 도메인 이름입니다...

  92. // 합법적인 인터넷 호스트 이름의 구문은 RFC-952에 지정되었습니다.

  93. // 이에 따라 호스트 이름 구문의 한 측면이 변경되었습니다.
  94. // 첫 번째 문자에 대한 제한이 완화되어
  95. // 문자 또는 숫자.
  96. // (http://tools.ietf.org/html/rfc1123#section-2.1)
  97. //
  98. // NB RFC 1123은 RFC 1035를 업데이트하지만 이는 현재 RFC를 읽어도 명확하지 않습니다. 1035.
  99. //
  100. // 이메일과 웹을 포함한 대부분의 일반적인 애플리케이션은 일반적으로...이스케이프된 문자열을 허용하지 않습니다.
  101. // (http://tools.ietf.org/html/rfc3696 #section-2)
  102. //
  103. // 알파벳 문자, 숫자, 하이픈 이외의 문자는 도메인 이름에 표시되어서는 안 됩니다.
  104. // SMTP 클라이언트 또는 서버 라벨
  105. // ( http://tools.ietf.org/html/rfc5321#section-4.1.2)
  106. //
  107. // RFC5321에서는 SMTP 목적으로 도메인 이름 뒤에 점을 사용하는 것을 금지합니다.
  108. // (http://tools.ietf.org/html/rfc5321#section-4.1.2)
  109. $matches = array();
  110. $groupCount = preg_match_all('/(?:[0-9a-zA-Z][0-9a-zA-Z-]{0,61}[0-9a-zA-Z]|[a- zA-Z])(?:\.|$)|(.)/', $domain, $matches);
  111. $level = count($matches[0]);

  112. if ($level == 1) false를 반환합니다. // 메일 호스트는 TLD

  113. 일 수 없습니다. $TLD = $matches[0][$level - 1];

  114. if (substr($TLD, strlen($TLD) - 1, 1) === '.') return false; // TLD는 점으로 끝날 수 없습니다.
  115. if (preg_match('/^[0-9] $/', $TLD) > 0) return false; // TLD는 모두 숫자일 수 없습니다

  116. // 일치하지 않는 문자가 있는지 확인

  117. array_multisort($matches[1], SORT_DESC);
  118. if ($matches[1][0] !== '') 반환 false; // 도메인에 잘못된 문자가 있거나 63자를 초과하는 라벨이 있습니다

  119. // DNS를 확인하시겠습니까?

  120. if ($checkDNS && function_exists('checkdnsrr')) ​​{
  121. if (!(checkdnsrr($domain, 'A') || checkdnsrr($domain, 'MX'))) {
  122. return 거짓; // 도메인이 실제로 존재하지 않습니다
  123. }
  124. }

  125. // 다른 모든 요소를 ​​제거하고 남는 것이 진실임에 틀림없다.

  126. // (Sherlock Holmes, The Sign of Four)
  127. return true;
  128. }
  129. }
  130. function unitTest ($email, $reason = '') {

  131. $expected = ($reason === '') ? 사실 : 거짓;
  132. $valid = is_email($email);
  133. $not = ($valid) ? '' : ' 아니다';
  134. $예상치 못한 = ($valid !== $expected) ? ' 이건 예상치 못한 일이었습니다!' : '';
  135. $reason = ($reason === '') ? "" : " 이유: $reason";
  136. return "$email 주소는$유효하지 않습니다.$unexpected$reason
    n";
  137. }
  138. // 이메일 유효성 검사기 테스트 사례(Dominic Sayers, 2009년 1월)

  139. // 유효한 주소
  140. echo unitTest('first.last@example.com');
  141. echo unitTest('1234567890123456789012345678901234567890123456789012345678901234@example.com');
  142. echo unitTest('"first last"@example.com');
  143. echo unitTest('"first\"last"@example.com'); // 이것이 유효한지 확실하지 않습니다.
  144. echo unitTest('first\@last@example.com');
  145. echo unitTest('"first@last"@example.com');
  146. echo unitTest('first\\last@example.com') // 작은따옴표 문자열에서도 이스케이프됩니다. 이것은 테스트 중입니다 "first\last"@example.com
  147. echo unitTest('first.last@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23 456789.x23456789.x23456789.x23456789.x23456789 .
  148. x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x234 5');
  149. echo unitTest('first.last@[12.34.56.78]')
  150. echo unitTest('first.last@[IPv6:::12.34.56.78]')
  151. echo unitTest('first.last@[IPv6:1111:2222:3333::4444:12.34.56.78]' );
  152. echo 단위 테스트('first.last@[IPv6:1111:2222:3333:4444:5555:6666:12.34.56.78]')
  153. echo 단위 테스트('first.last@[IPv6:: :1111:2222:3333:4444:5555:6666]');
  154. echo unitTest('first.last@[IPv6:1111:2222:3333::4444:5555:6666]');
  155. echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666::]');
  156. echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888]');
  157. echo unitTest('first.last@x23456789012345678901234567890123456789012345678901234567890123.example.com');
  158. echo unitTest('first.last@1xample.com');
  159. echo unitTest('first.last@123.example.com');

  160. // 잘못된 주소

  161. echo unitTest('first.last', "아니요 @ ");
  162. echo unitTest('@example.com', "로컬 부분 없음");
  163. echo unitTest('12345678901234567890123456789012345678901234567890123456789012345@example.com', "로컬 부분이 64자를 초과합니다.");
  164. echo unitTest('.first.last@example.com', "로컬 부분은 점으로 시작합니다.");
  165. echo unitTest('first.last.@example.com', "로컬 부분은 점으로 끝납니다.");
  166. echo unitTest('first..last@example.com', "로컬 부분에 연속된 점이 있습니다.");
  167. echo unitTest('"first"last"@example.com', "로컬 부분에 이스케이프 처리되지 않은 제외 문자가 포함되어 있습니다.");
  168. echo unitTest('first\\@last@example.com', "로컬 부분에 다음이 포함되어 있습니다." 이스케이프되지 않은 제외 문자");
  169. echo unitTest('first.last@', "도메인 없음");
  170. echo unitTest('first.last@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789. x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.
  171. x23456789.x23456789.x23456789.x23456789.x23456 789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456', "도메인이 255자를 초과합니다.");
  172. echo unitTest('first.last@[.12.34.56.78]', "IPv4 주소 앞에 올 수 있는 문자만 ':'입니다.")
  173. echo unitTest('first.last@[12.34.56.789] ', "IPv4로 해석할 수 없으므로 IPv6 태그가 없습니다.")
  174. echo unitTest('first.last@[::12.34.56.78]', "IPv6 태그가 없습니다.")
  175. echo unitTest('first.last@[IPv5:::12.34.56.78]', "IPv6 태그가 잘못되었습니다.")
  176. echo unitTest('first.last@[IPv6:1111:2222:3333::4444:5555 :12.34.56.78]', "IPv6 그룹이 너무 많습니다(최대 4개)");
  177. echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:12.34.56.78]', "IPv6 그룹이 충분하지 않습니다.");
  178. echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:12.34.56.78]', "IPv6 그룹이 너무 많습니다(최대 6개)");
  179. echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777]', "IPv6 그룹이 충분하지 않습니다.");
  180. echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888:9999]', "IPv6 그룹이 너무 많습니다(최대 8개)");
  181. echo unitTest('first.last@[IPv6:1111:2222::3333::4444:5555:6666]', "'::'이 너무 많습니다(없음 또는 1일 수 있음)");
  182. echo unitTest('first.last@[IPv6:1111:2222:3333::4444:5555:6666:7777]', "IPv6 그룹이 너무 많습니다(최대 6개)");
  183. echo unitTest('first.last@[IPv6:1111:2222:333x::4444:5555]', "x는 IPv6 주소에서 유효하지 않습니다.");
  184. echo unitTest('first.last@[IPv6:1111:2222:33333::4444:5555]', "33333은 IPv6 주소에서 유효한 그룹이 아닙니다.");
  185. echo unitTest('first.last@example.123', "TLD는 모두 숫자일 수 없습니다.");
  186. echo unitTest('first.last@com', "메일 호스트는 두 번째 이하 수준이어야 합니다.");
  187. echo unitTest('first.last@-xample.com', "레이블은 하이픈으로 시작할 수 없습니다.");
  188. echo unitTest('first.last@exampl-.com', "레이블은 하이픈으로 끝날 수 없습니다."); echo unitTest('Abc\@def@example.com');
  189. echo unitTest('Fred\ Bloggs@example.com');
  190. echo unitTest('Joe.\\Blow@example.com');
  191. echo unitTest('"Abc@def"@example.com');
  192. echo unitTest('"Fred Bloggs"@example.com');
  193. echo unitTest('user Mailbox@example.com');
  194. echo unitTest('customer/department=shipping@example.com');
  195. echo unitTest('$A12345@example.com');
  196. echo unitTest('!def!xyz�c@example.com');
  197. echo unitTest('_somename@example.com');

  198. // Doug Lovell의 테스트 사례(LinuxJournal, 2007년 6월, http://www.linuxjournal.com/ 기사/9585)

  199. echo unitTest("dclo@us.ibm.com");
  200. echo unitTest("abc\@def@example.com");
  201. echo unitTest("abc\\@example.com");
  202. echo unitTest("Fred\ Bloggs@example.com");
  203. echo unitTest("Joe.\\Blow@example.com");
  204. echo unitTest(""Abc@def"@example.com");
  205. echo unitTest(""Fred Bloggs"@example.com");
  206. echo unitTest("customer/department=shipping@example.com");
  207. echo unitTest("$A12345@example.com");
  208. echo unitTest("!def!xyz�c@example.com");
  209. echo unitTest("_somename@example.com");
  210. echo unitTest("user Mailbox@example.com");
  211. echo unitTest("peter.piper@example.com");
  212. echo unitTest("Doug\ \"Ace\"\ Lovell@example.com");
  213. echo unitTest(""Doug \"Ace\" L."@example.com");
  214. echo unitTest("abc@def@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
  215. echo unitTest("abc\\@def@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
  216. echo unitTest("abc\@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
  217. echo unitTest("@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
  218. echo unitTest("doug@", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
  219. echo unitTest(""qu@example.com", "Doug Lovell이 이것이 실패해야 한다고 말합니다");
  220. echo unitTest("ote"@example.com", "Doug Lovell이 이것이 실패해야 한다고 말합니다");
  221. echo unitTest(".dot@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
  222. echo unitTest("dot.@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
  223. echo unitTest("two..dot@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
  224. echo unitTest(""Doug "Ace" L."@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
  225. echo unitTest("Doug\ \"Ace\"\ L\.@example.com", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
  226. echo unitTest("hello world@example.com", "Doug Lovell이 이것이 실패해야 한다고 말했습니다.");
  227. echo unitTest("gatsby@f.sc.ot.t.f.i.tzg.era.l.d.", "Doug Lovell은 이것이 실패해야 한다고 말했습니다.");
  228. ?>

复代码


원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿