検索
ホームページバックエンド開発PHPチュートリアルPHP は RFC 準拠の電子メール アドレス検証を実装します

  1. /*
  2. Copyright 2009 Dominic Sayers
  3. (dominic_sayers@hotmail.com)
  4. (http://www.dominicsayers.com)
  5. このソース ファイルは Common Public Attribution License バージョンの対象です1.0 (CPAL) ライセンス。

  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. から区切られた「ローカル部分」で構成されます。 // 「ドメイン部分」 (完全修飾ドメイン名) は、アットマーク ("@")。
  17. // (http://tools.ietf.org/html/rfc3696#section-3)
  18. $index = strrpos($email,'@');
  19. if ($index === false) は false を返します。 // アットマークはありません

  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 ) false を返します。 // ドットが間違った場所にあります
  33. //

  34. // アットマーク ("@")、バックスラッシュ、二重引用符、カンマ、または角括弧以外の ASCII グラフィック (印刷) 文字は、
  35. // 引用符なしで使用できます。 除外される文字のリスト
  36. // が出現する場合は、引用符で囲む必要があります
  37. // (http://tools.ietf.org/html/rfc3696#section-3)
  38. if (preg_match('/^" (?:.)*"$/', $localPart) > 0) {
  39. // ローカル部分は引用符で囲まれた文字列
  40. if (preg_match('/(?:.)+[^\\]"(?: .)+/', $localPart) > return false // 引用符付き文字列内のエスケープされていない引用符
  41. } else {
  42. if (preg_match('/[ @\[\]\\",]/', $ localPart) > 0)
  43. // 除外された文字がすべてエスケープされていることを確認します
  44. $stripped = preg_replace('/\\[ @\[\]\\",]/', '', $localPart);
  45. if (preg_match ('/[ @\[\]\\",]/', $tripped) > 0) 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 = array();
  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 を返します。 // アドレス内の IPv6 グループが多すぎます
  84. }
  85. // 一致しない文字をチェック

  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. // ホスト名の構文の 1 つの側面が変更されました:
  94. // 最初の文字の制限が緩和され、
  95. // 文字または桁。
  96. // (http://tools.ietf.org/html/rfc1123#section-2.1)
  97. //
  98. // NB RFC 1123 は RFC 1035 を更新しますが、これは現時点では RFC 1035 を読んでも明らかではありません。
  99. //
  100. // 電子メールや Web などの最も一般的なアプリケーションでは、通常、エスケープされた文字列は許可されません
  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) === '.') は 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. false を返します。 // ドメインは実際には存在しません
  123. }
  124. }
  125. // 他の要素をすべて削除し、残ったものが真実でなければなりません。

  126. // (シャーロック ホームズ、The Sign of Four)
  127. return true;
  128. }
  129. }
  130. 関数unitTest ($email, $reason = '') {

  131. $expected = ($reason === '') ?真/偽;
  132. $valid = is_email($email);
  133. $not = ($valid) ? '' : ' ない';
  134. $unexpected = ($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. echounitTest('1234567890123456789012345678901234567890123456789012345678901234@example.com');
  142. echounitTest('"最初と最後"@example.com');
  143. echounitTest('"first\"last"@example.com'); // これが有効かどうか完全にはわかりません
  144. echounitTest('first\@last@example.com');
  145. echounitTest(' "first@last"@example.com');
  146. echounitTest('first\\last@example.com'); // これは一重引用符の文字列でもエスケープされるため、「first\last」をテストしていることに注意してください。 @example.com
  147. echo UnitTest('first.last@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x 23456789.x23456789.x23456789.x23456789.
  148. x23456789.x23456789.x23456789.x23456789。 x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x2345');
  149. echounitTest('first.last@[12.34.56.78]'); first.last@[IPv6:::12.34 .56.78]');
  150. エコーユニットテスト('first.last@[IPv6:1111:2222:3333::4444:12.34.56.78]');
  151. エコーユニットテスト('first.last@[IPv6:1111:2222: 3333:4444:5555:6666:12.34.56.78]');
  152. echounitTest('first.last@[IPv6:::1111:2222:3333:4444:5555:6666]'); .last@[IPv6:1111:2222:3333::4444:5555:6666]');
  153. echounitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666::]');
  154. echounitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888]');
  155. echounitTest('first.last@x23456789012345678901234567890123456789012345678901234567890123.example.com');
  156. echounitTest('first.last@1xample.com');
  157. echounitTest('first.last@123.example.com');
  158. // 無効なアドレス

  159. echounitTest('first.last', "No @");
  160. echounitTest('@example.com', "ローカル部分がありません");
  161. echo UnitTest('12345678901234567890123456789012345678901234567890123456789012345@example.com', "64 文字を超えるローカル部分");
  162. echounitTest('.first.last@example.com', "ローカル部分はドットで始まります");
  163. echounitTest('first.last.@example.com', "ローカル部分はドットで終わります");
  164. echounitTest('first..last@example.com', "ローカル部分に連続したドットがあります");
  165. echo UnitTest('"first"last"@example.com', "ローカル部分にはエスケープされていない除外文字が含まれています");
  166. echo UnitTest('first\\@last@example.com', "ローカル部分にはエスケープされていない除外文字が含まれています" );
  167. echo unitTest('first.last@', "ドメインなし"); 9.x23456789.x23456789.x23456789。 x23456789.x23456789.x23456789.
  168. x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x2345678 9.x23456789.x23456789.x23456', "ドメインが 255 文字を超えています");
  169. echounitTest('first.last@[ .12.34.56.78]', "IPv4 アドレスの前に付けられる文字は ':' のみです");
  170. echo UnitTest('first.last@[12.34.56.789]', "IPv4 として解釈できないため、IPv6 タグは欠落しています");
  171. echo UnitTest('first.last@[::12.34.56.78]', "IPv6 タグが欠落しています");
  172. echo UnitTest('first.last@[IPv5:::12.34.56.78]', "IPv6 タグが間違っています");
  173. echounitTest('first.last@[IPv6:1111:2222:3333::4444:5555:12.34.56.78]', "IPv6 グループが多すぎます (最大 4 つ)"); echounitTest('first.last@[IPv6:1111:2222:3333:4444:5555:12.34.56.78]', "IPv6 グループが不足しています");
  174. echounitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:12.34.56.78]', "IPv6 グループが多すぎます (最大 6 つ)");
  175. echounitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777]', "IPv6 グループが不足しています");
  176. echounitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888:9999]', "IPv6 グループが多すぎます (最大 8 つ)");
  177. echounitTest('first.last@[IPv6:1111:2222::3333::4444:5555:6666]', "「::」が多すぎます (なしまたは 1 つ)");
  178. echounitTest('first.last@[IPv6:1111:2222:3333::4444:5555:6666:7777]', "IPv6 グループが多すぎます (最大 6 つ)");
  179. echounitTest('first.last@[IPv6:1111:2222:333x::4444:5555]', "x は IPv6 アドレスでは無効です");
  180. echounitTest('first.last@[IPv6:1111:2222:33333::4444:5555]', "33333 は IPv6 アドレスの有効なグループではありません");
  181. echounitTest('first.last@example.123', "TLD をすべて数字にすることはできません");
  182. echounitTest('first.last@com', "メールホストは 2 番目以下のレベルである必要があります");
  183. echounitTest('first.last@-xample.com', "ラベルをハイフンで始めることはできません");
  184. echounitTest('first.last@exampl-.com', "ラベルはハイフンで終わることはできません");
  185. echo UnitTest('first.last@x234567890123456789012345678901234567890123456789012345678901234.example.com', "ラベルは 63 オクテットを超えることはできません");
  186. // RFC3696 のテスト ケース (2004 年 2 月、http://tools.ietf.org/html/rfc3696#section-3)

  187. echo UnitTest('Abc\@def@example.com');
  188. echounitTest('Fred\ Bloggs@example.com');
  189. echounitTest('Joe.\\Blow@example.com');
  190. echounitTest('"Abc@def"@example.com');
  191. echounitTest('"Fred Bloggs"@example.com');
  192. echounitTest('user+mailbox@example.com');
  193. echounitTest('customer/Department=shipping@example.com');
  194. echounitTest('$A12345@example.com');
  195. echounitTest('!def!xyz%abc@example.com');
  196. echo UnitTest('_somename@example.com');
  197. // Doug Lovell のテスト ケース (LinuxJournal、2007 年 6 月、http://www.linuxjournal.com/article/9585)

  198. echounitTest("dclo@us.ibm.com");
  199. echounitTest("abc\@def@example.com");
  200. echounitTest("abc\\@example.com");
  201. echounitTest("Fred\ Bloggs@example.com");
  202. echounitTest("Joe.\\Blow@example.com");
  203. echounitTest(""Abc@def"@example.com");
  204. echounitTest(""Fred Bloggs"@example.com");
  205. echounitTest("customer/Department=shipping@example.com");
  206. echounitTest("$A12345@example.com");
  207. echounitTest("!def!xyz%abc@example.com");
  208. echounitTest("_somename@example.com");
  209. echounitTest("user+mailbox@example.com");
  210. echounitTest("peter.piper@example.com");
  211. echo UnitTest("Doug\ \"Ace\"\ Lovell@example.com");
  212. echounitTest(""Doug \"Ace\" L."@example.com");
  213. echo UnitTest("abc@def@example.com", "Doug Lovell 氏は、これは失敗するはずだと言っています");
  214. echounitTest("abc\\@def@example.com", "Doug Lovell 氏は、これは失敗するはずだと言っています");
  215. echounitTest("abc\@example.com", "Doug Lovell 氏は、これは失敗するはずだと言っています");
  216. echounitTest("@example.com", "Doug Lovell 氏は、これは失敗するはずだと言っています");
  217. echounitTest("doug@", "Doug Lovell はこれは失敗するはずだと言います");
  218. echo UnitTest(""qu@example.com", "Doug Lovell 氏はこれは失敗するはずだと言います");
  219. echo UnitTest("ote"@example.com", "Doug Lovell 氏はこれは失敗するはずだと言います");
  220. echounitTest(".dot@example.com", "Doug Lovell 氏は、これは失敗するはずだと言っています");
  221. echo UnitTest("dot.@example.com", "Doug Lovell 氏は、これは失敗するはずだと言っています");
  222. echo UnitTest("two..dot@example.com", "Doug Lovell 氏は、これは失敗するはずだと言っています");
  223. echounitTest(""Doug "Ace" L."@example.com", "Doug Lovell はこれは失敗するはずと言っています");
  224. echounitTest("Doug\ \"Ace\"\ L\.@example.com", "Doug Lovell はこれは失敗するはずと言っています");
  225. echounitTest("hello world@example.com", "Doug Lovell 氏は、これは失敗するはずだと言っています");
  226. echounitTest("gatsby@f.sc.ot.t.f.i.tzg.era.l.d.", "Doug Lovell はこれは失敗するはずと言っています");
  227. ?>
复制帽


声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
トラフィックの高いウェブサイトのPHPパフォーマンスチューニングトラフィックの高いウェブサイトのPHPパフォーマンスチューニングMay 14, 2025 am 12:13 AM

thesecrettokeepingaphp-poweredwebsterunningsmootlyunderheavyloadinvolvesseveralkeystrategies:1)emform opcodecoduceSciptionexecutiontime、2)aatabasequerycachingwithiThing withiThistolessendavasoload、

PHPでの依存関係注射:初心者向けのコード例PHPでの依存関係注射:初心者向けのコード例May 14, 2025 am 12:08 AM

コードをより明確かつ維持しやすくするため、依存関係が関心(DI)に注意する必要があります。 1)DIは、クラスを切り離すことにより、よりモジュール化されます。2)テストとコードの柔軟性の利便性を向上させ、3)DIコンテナを使用して複雑な依存関係を管理しますが、パフォーマンスの影響と円形の依存関係に注意してください。

PHPパフォーマンス:アプリケーションを最適化することは可能ですか?PHPパフォーマンス:アプリケーションを最適化することは可能ですか?May 14, 2025 am 12:04 AM

はい、最適化されたAphPossibleandessention.1)CachingingusapCutoredatedAtabaseload.2)最適化、効率的なQueries、およびConnectionPooling.3)EnhcodeCodewithBultinctions、Avoididingglobalbariables、およびUsingopcodeching

PHPパフォーマンスの最適化:究極のガイドPHPパフォーマンスの最適化:究極のガイドMay 14, 2025 am 12:02 AM

keyStrategIestsoSificlyvoostphpappliceperformanceare:1)useopcodecachinglikeToreexecutiontime、2)最適化abaseの相互作用とプロペラインデックス、3)3)構成

PHP依存性噴射コンテナ:クイックスタートPHP依存性噴射コンテナ:クイックスタートMay 13, 2025 am 12:11 AM

aphpDependencyInjectionContaineriSATOULTAINATINAGECLASSDEPTINCIES、強化測定性、テスト可能性、および維持可能性。

PHPの依存噴射対サービスロケーターPHPの依存噴射対サービスロケーターMay 13, 2025 am 12:10 AM

SELECT DEPENTENCINGINOFCENT(DI)大規模なアプリケーションの場合、ServicElocatorは小さなプロジェクトまたはプロトタイプに適しています。 1)DIは、コンストラクターインジェクションを通じてコードのテスト可能性とモジュール性を改善します。 2)ServiceLocatorは、センター登録を通じてサービスを取得します。これは便利ですが、コードカップリングの増加につながる可能性があります。

PHPパフォーマンス最適化戦略。PHPパフォーマンス最適化戦略。May 13, 2025 am 12:06 AM

phpapplicationscanbeoptimizedforspeedandEfficiencyby:1)enabingopcacheinphp.ini、2)PreparedStatementswithpordatabasequeriesを使用して、3)LoopswithArray_filterandarray_mapfordataprocessing、4)の構成ngincasaSearverseproxy、5)

PHPメールの検証:電子メールが正しく送信されるようにしますPHPメールの検証:電子メールが正しく送信されるようにしますMay 13, 2025 am 12:06 AM

PHPemailvalidationinvolvesthreesteps:1)Formatvalidationusingregularexpressionstochecktheemailformat;2)DNSvalidationtoensurethedomainhasavalidMXrecord;3)SMTPvalidation,themostthoroughmethod,whichchecksifthemailboxexistsbyconnectingtotheSMTPserver.Impl

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール