32

さまざまな投稿を読んだ後、REGEX を使用して電子メールが有効かどうかを確認するのではなく、単純に PHP の組み込みの filter_var 関数を使用することにしました。番号が含まれているためにメールが無効であると通知されるまでは、問題なく機能しているように見えました。

つまり、name@domain.com は機能しますが、name2@domain.com は機能しません。

私は何かを見逃していますか、それともfilter_var($email, FILTER_VALIDATE_EMAIL)本当に効果がありませんか?

4

4 に答える 4

34

PHP 5.3.3 フィルター コードで使用される正規表現は、電子メール アドレス検証に関する Michael Rushton のブログに基づいています。あなたが言及したケースではうまくいくようです。

電子メール アドレス検証の正規表現の比較のオプションのいくつかを確認することもできます(PHP で現在使用されている正規表現は、テスト済みのものの 1 つです)。

次に、より好きな正規表現を選択して、 への呼び出しで使用できますpreg_match()

または、正規表現を取得して、ファイル PHP/ext/filter/logical_filter.c の function を置き換え、php_filter_validate_email()PHP を再構築することもできます。

于 2010-09-16T00:39:26.093 に答える
5

name2@domain.com は正常に動作しているようです: http://codepad.org/5HDgMW5i

しかし、SO であっても、問題があると不平を言っている人を確かに見てきました。おそらく、それには問題がありますが、正規表現ソリューションにも問題があります。メールアドレスの仕様は非常に複雑です ( RFC XXXX )。

そのため、メールを確認するための唯一の解決策は、そのアドレスにメールを送信してアクションを要求することです (例: 登録スクリプトの場合は、確認リンクをクリックするように依頼します)。

于 2010-09-16T00:25:29.100 に答える
1
function isValidEmail($email, $checkDNS = false)
{

    $valid = (
            /* Preference for native version of function */
            function_exists('filter_var') and filter_var($email, FILTER_VALIDATE_EMAIL)
            ) || (
                /* The maximum length of an e-mail address is 320 octets, per RFC 2821. */
                strlen($email) <= 320
                /*
                 * The regex below is based on a regex by Michael Rushton.
                 * However, it is not identical. I changed it to only consider routeable
                 * addresses as valid. Michael's regex considers a@b a valid address
                 * which conflicts with section 2.3.5 of RFC 5321 which states that:
                 *
                 * Only resolvable, fully-qualified domain names (FQDNs) are permitted
                 * when domain names are used in SMTP. In other words, names that can
                 * be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed
                 * in Section 5) are permitted, as are CNAME RRs whose targets can be
                 * resolved, in turn, to MX or address RRs. Local nicknames or
                 * unqualified names MUST NOT be used.
                 *
                 * This regex does not handle comments and folding whitespace. While
                 * this is technically valid in an email address, these parts aren't
                 * actually part of the address itself.
                 */
                and preg_match_all(
                    '/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?))'.
                    '{255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?))'.
                    '{65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|'.
                    '(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))'.
                    '(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|'.
                    '(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|'.
                    '(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})'.
                    '(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126})'.'{1,}'.
                    '(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|'.
                    '(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|'.
                    '(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::'.
                    '(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|'.
                    '(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|'.
                    '(?:(?!(?:.*[a-f0-9]:){5,})'.'(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::'.
                    '(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|'.
                    '(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|'.
                    '(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD',
                    $email)
            );

    if( $valid )
    {
        if( $checkDNS && ($domain = end(explode('@',$email, 2))) )
        {
            /*
            Note:
            Adding the dot enforces the root.
            The dot is sometimes necessary if you are searching for a fully qualified domain
            which has the same name as a host on your local domain.
            Of course the dot does not alter results that were OK anyway.
            */
            return checkdnsrr($domain . '.', 'MX');
        }
        return true;
    }
    return false;
}


//-----------------------------------------------------------------

    var_dump(isValidEmail('nechtan@tagon8inc.com', true));
    // bool(true)
于 2013-04-08T02:22:53.497 に答える
1

そのフィルターは最近改良されました。 http://codepad.org/Lz5m2S2N - コードパッドで使用されているバージョンでは、ケースが正しくフィルタリングされているようです

http://bugs.php.net/49576およびhttp://svn.php.net/viewvc/php/php-src/trunk/ext/filter/logical_filters.cも参照し てください。正規表現はかなり怖いです。

于 2010-09-16T00:35:43.413 に答える