Как проверить электронную почту в PHP?

Как я могу подтвердить, что входное значение является действительным адресом электронной почты, используя php5. Теперь я использую этот код

function isValidEmail($email){ 
     $pattern = "^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"; 

     if (eregi($pattern, $email)){ 
        return true; 
     } 
     else { 
        return false; 
     }    
} 

но он показывает устаревшую ошибку. Как я могу исправить эту проблему. Пожалуйста помогите.


person learner    schedule 02.05.2011    source источник
comment
Правильный ответ уже был дан, но относительно устаревшей проблемы: использование регулярных выражений POSIX (от которых eregi является функцией) не рекомендуется. Вместо этого используйте PCRE.   -  person Felix Kling    schedule 02.05.2011
comment
Кстати, ваше регулярное выражение совершенно неверно. Некоторые полностью действующие адреса будут отмечены вашей функцией как недопустимые. Фильтрация адресов электронной почты с помощью регулярного выражения - это кошмар.   -  person Artefact2    schedule 02.05.2011
comment
Вам следует использовать стандарт RFC 822, и вот хорошая статья Анализ адресов электронной почты в PHP.   -  person kta    schedule 06.01.2014
comment
Держитесь подальше от regex и filter_var() решений для проверки электронной почты. См. Этот ответ: stackoverflow.com/a/42037557/953833   -  person Jabari    schedule 04.02.2017


Ответы (6)


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

filter_var($email, FILTER_VALIDATE_EMAIL)

Если вы не хотите изменять свой код, основанный на вашей функции, просто выполните:

function isValidEmail($email){ 
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

Примечание. Для других целей (где вам нужно Regex) устаревшее семейство функций ereg (POSIX Regex Functions) следует заменить семейством preg (PCRE Regex Functions). Есть небольшое количество отличий, достаточно прочитать Инструкцию.

Обновление 1: как указано @binaryLV:

В PHP 5.3.3 и 5.2.14 была ошибка, связанная с FILTER_VALIDATE_EMAIL, которая приводила к ошибке segfault при проверке больших значений. . Простой и безопасный способ решения этой проблемы - использовать strlen() до filter_var(). Я не уверен насчет версии 5.3.4, но написано, что некоторые версии моментальных снимков 5.3.4 также были затронуты.

Эта ошибка уже исправлена.

Обновление 2: этот метод, конечно же, проверит bazmega@kapa как действительный адрес электронной почты, потому что на самом деле это действительный адрес электронной почты. Но в большинстве случаев в Интернете вы также хотите, чтобы адрес электронной почты имел TLD: [email protected]. Как предлагается в этом сообщении в блоге (ссылка опубликована @Istiaque Ahmed), вы можете увеличить filter_var() с помощью регулярного выражения который проверит наличие точки в части домена (однако не будет проверять наличие действительного TLD):

function isValidEmail($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) 
        && preg_match('/@.+\./', $email);
}

Как отметил @Eliseo Ocampos, эта проблема только существует до PHP 5.3, в той версии они изменили регулярное выражение, и теперь он выполняет эту проверку, так что вам не нужно.

person kapa    schedule 02.05.2011
comment
+1 Тем не менее, вы можете упомянуть, что это доступно только в PHP 5.2.x и выше. :-) - person John Parker; 02.05.2011
comment
@middaparka: Поскольку OP получает устаревшее сообщение для eregi, похоже, он использует PHP 5.3. Но да, об этом важно упомянуть (для других)). - person Felix Kling; 02.05.2011
comment
@middaparka Спасибо, добавил. Я пропустил это по той же причине, что объяснил @Felix, но да, другие могут быть заинтересованы. - person kapa; 02.05.2011
comment
В PHP 5.3.3 и 5.2.14 была ошибка (bugs.php.net/52929), связанная с FILTER_VALIDATE_EMAIL, что привело к ошибке segfault при проверке больших значений. Простой и безопасный способ решения этой проблемы - использовать strlen() перед filter_val(). Я не уверен насчет версии 5.3.4, но написано, что некоторые версии моментальных снимков 5.3.4 также были затронуты. - person binaryLV; 02.05.2011
comment
@binaryLV, filter_val или filter_var? - person Istiaque Ahmed; 21.11.2012
comment
@ bažmegakapa, я думаю, адрес электронной почты следует обрезать перед финальным тестированием. Процесс проверки в ответе не проверяет наличие точки в адресе. return filter_var($email, FILTER_VALIDATE_EMAIL) && preg_match('/@.+\./', $email); - проверяет наличие точки в части доменного имени. Также необходимо целочисленное преобразование возвращаемого значения. Его можно найти здесь: electrictoolbox.com/php-email-validation-filter-var-updated. - person Istiaque Ahmed; 21.11.2012
comment
@IstiaqueAhmed Полезный ресурс, обновлю свой ответ. Но у вас есть недоразумение: возвращаемое значение, конечно, не обязательно должно быть преобразовано в целое число - блоггер делает это только для того, чтобы echo правильно отображал логическое значение. - person kapa; 21.11.2012
comment
@Istiaque Ahmed, возможно, опечатка полуторагодовалой давности. - person binaryLV; 21.11.2012
comment
@kapa, Собственно проверять на точку в доменной части больше не нужно. См. svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/filter/ - person Eliseo Ocampos; 10.12.2013
comment
Я просто хотел бы отметить, что эта опция подкреплена проверкой домена / MX-записи, вы можете быть уверены, что сервер также действительно сможет обрабатывать электронные письма, которые вы ему отправляете. - person sg3s; 03.02.2014
comment
Вы должны вернуть filter_var(...) !== false в своей функции, чтобы вернуть логическое значение (isValidEmail подразумевает возвращаемое логическое значение). - person stofl; 03.01.2016
comment
@stofl Вы правы, он также лучше соответствует исходной подписи OP. Отредактировано. - person kapa; 04.01.2016
comment
Извините, что откопал этот пост, но покрывает ли этот метод также SQL-инъекцию или аналогичные методы? - person Norman; 11.01.2016
comment
@Norman Этот метод охватывает проверку электронной почты. Он проверяет, содержит ли строка действительный адрес электронной почты. Никакая база данных не упоминается, поэтому она не имеет ничего общего с SQL-инъекцией. - person kapa; 11.01.2016
comment
@kapa и у всех: Простите, у меня плохо. Мне почему-то показалось, что этот метод не работает с htmlspecialchars. Но ошибка была где-то в другом месте. Спасибо за быстрый ответ. - person Norman; 11.01.2016
comment
Это подтвердит: $email = '"><script>alert(1);</script>"@test.com'; echo filter_var($email, FILTER_VALIDATE_EMAIL) - person sergio; 07.03.2016
comment
@sergio Это недействительный адрес электронной почты? - person kapa; 07.03.2016
comment
@kapa Он может вводить XSS, но filter_var ($ email, FILTER_VALIDATE_EMAIL) проверит его как действительный адрес электронной почты, поэтому нужно быть осторожным - person sergio; 07.03.2016
comment
@sergio Валидатор электронной почты проверяет электронные письма. Это его работа. Он не должен заботиться о XSS, SQL-инъекции и т. Д. Это другая часть вашего приложения. При выводе HTML следует принимать меры против XSS. - person kapa; 07.03.2016
comment
Важное замечание - в последнем обновлении вы немного изменили логику, так как удалили !== false. - person Tomer Gal; 19.07.2017
comment
эта функция не будет работать для писем с испанскими символами, такими как Sté[email protected] - person Coder anonymous; 26.12.2018

См. Примечания на странице http://www.php.net/manual/en/function.ereg.php:

Note:

Начиная с PHP 5.3.0, расширение регулярных выражений устарело в пользу расширения PCRE < / а>. Вызов этой функции выдаст уведомление E_DEPRECATED. См. список различий для получения помощи по преобразованию в PCRE. .

Note:

preg_match (), который использует синтаксис регулярных выражений, совместимый с Perl. , часто является более быстрой альтернативой ereg ().

person Sean Kelleher    schedule 02.05.2011

Это старый пост, но я поделюсь одним своим решением, потому что раньше никто не упоминал здесь ни одной проблемы.

Новый адрес электронной почты может содержать символы UTF-8 или специальные доменные имена, такие как .live, .news и т. Д.

Также я обнаружил, что некоторые адреса электронной почты могут быть на кириллице, и во всех случаях стандартное регулярное выражение или filter_var() не сработает.

Вот почему я решил это исправить:

function valid_email($email) 
{
    if(is_array($email) || is_numeric($email) || is_bool($email) || is_float($email) || is_file($email) || is_dir($email) || is_int($email))
        return false;
    else
    {
        $email=trim(strtolower($email));
        if(filter_var($email, FILTER_VALIDATE_EMAIL)!==false) return $email;
        else
        {
            $pattern = '/^(?!(?:(?:\\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';
            return (preg_match($pattern, $email) === 1) ? $email : false;
        }
    }
}

Эта функция отлично работает со всеми делами и форматами писем.

person Ivijan Stefan Stipić    schedule 10.11.2016

Я всегда использую это:

function validEmail($email){
    // First, we check that there's one @ symbol, and that the lengths are right
    if (!preg_match("/^[^@]{1,64}@[^@]{1,255}$/", $email)) {
        // Email invalid because wrong number of characters in one section, or wrong number of @ symbols.
        return false;
    }
    // Split it into sections to make life easier
    $email_array = explode("@", $email);
    $local_array = explode(".", $email_array[0]);
    for ($i = 0; $i < sizeof($local_array); $i++) {
        if (!preg_match("/^(([A-Za-z0-9!#$%&'*+\/=?^_`{|}~-][A-Za-z0-9!#$%&'*+\/=?^_`{|}~\.-]{0,63})|(\"[^(\\|\")]{0,62}\"))$/", $local_array[$i])) {
            return false;
        }
    }
    if (!preg_match("/^\[?[0-9\.]+\]?$/", $email_array[1])) { // Check if domain is IP. If not, it should be valid domain name
        $domain_array = explode(".", $email_array[1]);
        if (sizeof($domain_array) < 2) {
            return false; // Not enough parts to domain
        }
        for ($i = 0; $i < sizeof($domain_array); $i++) {
            if (!preg_match("/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$/", $domain_array[$i])) {
                return false;
            }
        }
    }

    return true;
}
person unbreak    schedule 12.02.2016
comment
@unbreak Я пробовал ваш код и обнаружил, что если вы передаете электронную почту как alex@., она всегда возвращает true, если это недействительный адрес электронной почты. - person Subhajit; 11.04.2018

Использовать:

var_dump(filter_var('[email protected]', FILTER_VALIDATE_EMAIL));
$validator = new EmailValidator();
$multipleValidations = new MultipleValidationWithAnd([
    new RFCValidation(),
    new DNSCheckValidation()
]);
$validator->isValid("[email protected]", $multipleValidations); //true
person Roman    schedule 20.03.2019

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

Перед проверкой адреса электронной почты: сначала удалите из электронной почты все недопустимые символы.

//This will Remove all illegal characters from email
$email = filter_var($email, FILTER_SANITIZE_EMAIL);

после этого подтвердите свой адрес электронной почты с помощью этой filter_var() функции.

filter_var($email, FILTER_VALIDATE_EMAIL)) // To Validate the email

Например,

<?php
$email = "[email protected]";

// Remove all illegal characters from email
$email = filter_var($email, FILTER_SANITIZE_EMAIL);

// Validate email
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo $email." is a valid email address";
} else {
    echo $email." is not a valid email address";
}
?>
person mufazmi    schedule 05.06.2020