簡體   English   中英

我應該使用filter_var來驗證電子郵件嗎?

[英]Should I use filter_var to validate email?

我有一個類在每次輸入發送到數據庫層之前驗證它。 請注意,我的問題不是逃避或任何事情。 我的數據庫層將處理SQL注入問題。 我想要做的就是驗證電子郵件是否有效,因為稍后該電子郵件可能被用作“發送到”。 例如,用戶將通過發送到電子郵件的鏈接恢復對其帳戶的訪問。 我讀了很多關於filter_var ,有很多人反對它,其他人也贊成。 將重點放在'我只是想驗證電子郵件而不是為數據庫或html或XSS或其他任何'過濾它,是否存在使用filter_var的問題?

是的你應該。

使用標准庫驗證而不是家庭釀造有一個好處:

  1. 許多眼球已經看到了你將要使用的代碼(好吧,至少有兩個),希望在將它合並到一個版本之前就具有電子郵件驗證方面的經驗。
  2. 它是經過單元測試的
  3. 其他人將使用相同的檢查和報告錯誤 ,你可以免費獲得這些修補程序的PHP更新。

但是,檢查電子郵件地址的格式只是第一道防線,如果您真的想知道它是否真實,則必須向其發送消息。

是的,你應該使用filter_var ,這是你如何合並它:

if( filter_var( $email ,FILTER_VALIDATE_EMAIL ) )
{
    /*
     * Rest of your code
     */
}

是。 checkdnsrr()在這里也值得一提。

filter_var()將批准看起來不完整的域,因為它可能在本地上下文中有效(例如某人@ localhost)。 這可能會導致人們錯過TLD或域名中的點的誤報(例如hattie.jacques@gmailcom)

通過在域上執行checkdnsrr()查找來捕獲這些 - 如果您可以找到域的MX記錄並且地址有效,那么您已經完成了最多的工作。

示例代碼:

if(filter_var($email, FILTER_VALIDATE_EMAIL)) 
{
    list($userName, $mailDomain) = explode("@", $email);
    if (!checkdnsrr($mailDomain, "MX"))
    {
        // Email is unreachable.
    }
}
else
{
    // Email is bad.
}

checkdnsrr()非常即時(根據我的經驗),我還沒有找到一個不起作用的環境。

不幸的是, filter_var在地址的本地部分(@之前)不支持UTF8,並且為了支持國際域名,您需要分別通過idn_to_ascii運行域名(這是一個麻煩且不明顯)。

這使得filter_var在我看來相當無用:越來越多的unicode電子郵件地址出現,更合法的電子郵件地址將會失敗,尤其是中國或巴西等國家,這些國家對這些地址有明顯的需求。 filter_var也不允許像root@localhost這樣的電子郵件地址,它們是有效的,可能在服務器上下文中很有用。

如果存在根據特定指令進行驗證的電子郵件庫 - 僅允許域名,或者像localhost這樣的任意主機,或者是否應該有效的自定義域的白名單,那將非常有用? 應該允許unicode嗎? 免費郵箱域名(如@ homail.com)的常見錯別字也應該失敗?

此外,以更具體的方式驗證某些域名是明智的 - hotmail.com目前不允許使用unicode字符,並且對可用字符有特定限制。 由於PHP應用程序中大多數使用的電子郵件地址都集中在100個不同的域上,因此可以用更好的方式驗證這些域名。 不幸的是,據我所知,還沒有這樣的庫存在。

我看到的一些評論與我的測試不符,所以我想指出我在PHP 5.x中找到的功能。 如果您首先SANITIZE電子郵件它將刪除您不想要的所有字符,那么您可以驗證。 我有兩個功能,以防有人想要做一個或另一個。

檢查電子郵件是否有效:

function isValidEmailAddress($email = '', $check_domain = false)
{
    if (empty($email)) {
        return false;
    } else {
        $success = true;
    }

    if (!filter_var((string) $email, FILTER_VALIDATE_EMAIL)) {
        $success = false;
    }
    if ($check_domain && $success) {
        list($name, $domain) = explode('@', trim($email) . "@");
        if (!checkdnsrr($domain, 'MX')) {
            $success = false;
        }
    }
    return array("success" => $success, "email" => $email);
}

刪除<>和UTF8等:

function sanitizeEmailAddress($email = '') {
    if (!empty($email)) {
        $email = filter_var(strtolower(trim($email)), FILTER_SANITIZE_EMAIL);
    }
    return $email;
}

樣品用法:

// test -- 
$list = array('goodÂ@bad.com', 'mikeq@google.com', 'puser@porsche.us', 'quick@us', '', '<yo@marist.edu>', 'hello@us.edu', 'rgil@yahoo.com', 'abc@2r.edu', 'one2@e3.edu', 'key@gen.us');

foreach($list as $email) {

    $ret = isValidEmailAddress( sanitizeEmailAddress($email), false );
    if ($ret['success']) {
        echo "GOOD " . $ret['email'];
    } else {
       echo "BAD  " .$email;
    }
        echo "\n";
    }

結果:

GOOD good@bad.com
GOOD mikeq@google.com
GOOD puser@porsche.us
BAD  quick@us
BAD  
GOOD yo@marist.edu
GOOD hello@us.edu
GOOD rgil@yahoo.com
GOOD abc@2r.edu
GOOD one2@e3.edu
GOOD key@gen.us

如果您使用域選項:$ ret = isValidEmailAddress(sanitizeEmailAddress($ email),true);

GOOD good@bad.com
GOOD mikeq@google.com
GOOD puser@porsche.us
BAD  quick@us
BAD  
GOOD yo@marist.edu
GOOD hello@us.edu
GOOD rgil@yahoo.com
BAD  abc@2r.edu
BAD  one2@e3.edu
BAD  key@gen.us

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM