Должен ли я использовать filter_var для проверки электронной почты?

У меня есть класс, который проверяет каждый вход, прежде чем я отправлю его на уровень базы данных. Обратите внимание, что моя проблема заключается не в побеге, а в чем-либо. Мой уровень базы данных будет обрабатывать проблему SQL Injection. Все, что я хочу сделать, это проверить, является ли сообщение действительным или нет, потому что позже этот адрес электронной почты может использоваться как "отправить". Например, пользователь восстановит доступ к своей учетной записи через ссылку, отправленную по электронной почте. Я много читал о filter_var, и есть куча людей, которые против этого, и другая группа в пользу. Уделение особого внимания "Я просто хочу проверить электронную почту, а не фильтровать ее для базы данных или для html или XSS или что-то еще", существует ли проблема с использованием filter_var?

Ответ 1

Да, вы должны.

Использование стандартной проверки библиотеки вместо домашнего brew имеет несколько преимуществ:

  • Многие глазные яблоки уже видели код (ну, по крайней мере, два), вы будете использовать, надеюсь, с опытом проверки подлинности еще до того, как он будет объединен в выпуск.
  • Это unit testing.
  • Другие люди будут использовать ту же проверку и сообщить об ошибках, и вы получите эти исправления бесплатно на обновлениях php.

Однако проверка формата адреса электронной почты является только первой строкой защиты, если вы действительно хотите знать, что это реально или нет, вам нужно будет отправить ей сообщение.

Ответ 2

Да, вы должны использовать filter_var, и именно так вы можете его включить:

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

Ответ 3

Да. Но checkdnsrr() также можно упомянуть здесь.

filter_var() будет одобрять домены, которые кажутся неполными, поскольку они могут быть действительными в локальном контексте (например, кто-то @localhost). Это может привести к ложным срабатываниям, когда люди просто пропускают TLD или точку в доменном имени (например, [email protected])

Поймайте их, выполнив 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() довольно мгновенный (по моему опыту), и я еще не нашел среду, в которой она не работает.

Ответ 4

К сожалению, filter_var не поддерживает UTF8 в локальной части (до @) адреса, а для поддержки международных доменных имен вам нужно будет запускать доменное имя через idn_to_ascii отдельно (что является проблемой и не очевидно).

Это делает filter_var довольно бесполезным на мой взгляд: чем больше адресов электронной почты unicode появляется в дикой природе, тем более законные адреса электронной почты потерпят неудачу, что особенно характерно для таких стран, как Китай или Бразилия, где существует очевидный спрос для этих адресов. filter_var также не разрешает адреса электронной почты, такие как [email protected], которые действительны и могут быть полезны в контексте сервера.

Было бы действительно полезно, если бы библиотека электронной почты существовала для проверки в соответствии с конкретными инструкциями - разрешены ли только доменные имена, а также произвольные хосты, такие как localhost, или есть ли белый список для пользовательских доменов, который должен быть действительным? Должен ли разрешаться unicode? Каковы распространенные опечатки для доменных имен freemail (например, @homail.com), которые также должны потерпеть неудачу?

Кроме того, проверка некоторых доменных имен более конкретным образом была бы разумной - hotmail.com не разрешает использовать символы Unicode и имеет определенные ограничения на используемые символы. Поскольку большинство используемых адресов электронной почты в приложениях PHP сосредоточены на возможно более чем 100 различных доменах, это может быть использовано для более точного подтверждения этих доменных имен. К сожалению, такой библиотеки пока нет, насколько я знаю.

Ответ 5

Некоторые из комментариев, которые я видел, не соответствовали моему тестированию, поэтому я хотел указать на функциональность, которую я нашел с помощью PHP 5.x. Если вы сначала SANITIZE по электронной почте, он удалит все символы, которые вам не нужны, тогда вы можете VALIDATE. У меня есть две функции, если кто-то хочет просто сделать то или другое.

Проверьте правильность адреса электронной почты:

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', '[email protected]', '[email protected]', '[email protected]', '', '<[email protected]>', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]');

foreach($list as $email) {

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

Результаты:

GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
BAD  [email protected]
BAD  
GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
GOOD [email protected]

если вы используете опцию домена: $ret = isValidEmailAddress (sanitizeEmailAddress ($ email), true);

GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
BAD  [email protected]
BAD  
GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
BAD  [email protected]
BAD  [email protected]
BAD  [email protected]