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

У меня есть эта функция для проверки адресов электронной почты:

function validateEMAIL($EMAIL) { $v = "/[a-zA-Z0-9_-.+]+@[a-zA-Z0-9-]+.[a-zA-Z]+/"; return (bool)preg_match($v, $EMAIL); } 

Это нормально для проверки правильности адреса электронной почты?

Самый простой и безопасный способ проверить, правильно ли сформирован адрес электронной почты, – использовать filter_var() :

 if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { // invalid emailaddress } 

Кроме того, вы можете проверить, определяет ли домен запись MX :

 if (!checkdnsrr($domain, 'MX')) { // domain is not valid } 

Но это все еще не гарантирует, что почта существует. Единственный способ узнать это – отправить письмо с подтверждением.


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

Попытка проверить адрес электронной почты с помощью регулярного выражения является «невозможной» задачей. Я хотел бы сказать, что это регулярное выражение, которое вы сделали, бесполезно. Есть три rfc в отношении адресов электронной почты и написания регулярных выражений, чтобы поймать неправильные адреса электронной почты и в то же время не имеют ложных срабатываний – это то, что никто из смертных не может сделать. Проверьте этот список для тестов (как неудачных, так и filter_var() регулярного выражения, используемого filter_var() PHP.

Даже встроенные функции PHP, почтовые клиенты или серверы не понимают это правильно. В большинстве случаев filter_var – лучший вариант.

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

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

  • rfc5322
  • RFC5321
  • rfc3696
  • rfc6531 (допускает символы Unicode, хотя многие клиенты / серверы не принимают его)

Обратите внимание: filter_var() уже указан только в PHP 5.2. Если вы хотите, чтобы он работал с более ранними версиями PHP, вы могли бы использовать регулярное выражение, используемое в PHP:

 <?php $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,}(?:(?:[az][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'; $emailaddress = 'test@gmail.com'; if (preg_match($pattern, $emailaddress) === 1) { // emailaddress is valid } 

PS Замечание о шаблоне регулярного выражения, используемом выше (из источника PHP). Похоже, есть некоторые авторские права на него Майкла Раштона . Как указано: «Не стесняйтесь использовать и распространять этот код, но, пожалуйста, сохраните это уведомление об авторских правах».

Для этого вы можете использовать filter_var .

 <?php function validateEmail($email) { return filter_var($email, FILTER_VALIDATE_EMAIL); } ?> 

Я думаю, вам лучше использовать встроенные фильтры PHP – в этом конкретном случае:

Он может возвращать значение true или false, когда он поставляется с параметром FILTER_VALIDATE_EMAIL .

По моему опыту, в решениях regex слишком много ложных срабатываний, а в filter_var() есть ложные негативы (особенно со всеми новыми TLD ).

Вместо этого лучше убедиться, что адрес имеет все необходимые части адреса электронной почты (пользователь, символ «@» и домен), а затем убедитесь, что сам домен существует.

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

Это метод, который я создал в классе Utility:

 public static function validateEmail($email) { // SET INITIAL RETURN VARIABLES $emailIsValid = FALSE; // MAKE SURE AN EMPTY STRING WASN'T PASSED if (!empty($email)) { // GET EMAIL PARTS $domain = ltrim(stristr($email, '@'), '@'); $user = stristr($email, '@', TRUE); // VALIDATE EMAIL ADDRESS if ( !empty($user) && !empty($domain) && checkdnsrr($domain) ) {$emailIsValid = TRUE;} } // RETURN RESULT return $emailIsValid; } 

Это не только подтвердит вашу электронную почту, но и дезинформирует ее для неожиданных символов:

 $email = $_POST['email']; $emailB = filter_var($email, FILTER_SANITIZE_EMAIL); if (filter_var($emailB, FILTER_VALIDATE_EMAIL) === false || $emailB != $email ) { echo "This email adress isn't valid!"; exit(0); } 

Ответ на это в «верхнем вопросе» об проверке электронной почты https://stackoverflow.com/a/41129750/1848217

Для меня правильный способ проверки электронной почты:

  1. Проверьте, что символ @ существует, и до и после него есть некоторые символы @ @: /^[^@]+@[^@]+$/
  2. Попробуйте отправить электронное письмо на этот адрес с некоторым «кодом активации».
  3. Когда пользователь «активирует» свой адрес электронной почты, мы увидим, что все правильно.

Конечно, вы можете показать предупреждение или всплывающую подсказку в интерфейсе, когда пользователь вводит «странное» электронное письмо, чтобы помочь ему избежать распространенных ошибок, таких как отсутствие точки в доменной части или пробелы без имени и т. Д. Но вы должны принять адрес «hello @ world», если пользователь действительно этого хочет.

Кроме того, вы должны помнить, что стандарт адреса электронной почты был и может эволюционировать, поэтому вы не можете просто набирать некоторое «стандартное допустимое» регулярное выражение раз и навсегда. И вы должны помнить, что некоторые конкретные интернет-серверы могут вывести некоторые детали общего стандарта и фактически работать с собственным «измененным стандартом».

Итак, просто проверьте @, подскажите пользователю об интерфейсе и отправьте письма с подтверждением по указанному адресу.

Если вы просто ищете фактическое регулярное выражение, которое допускает различные точки, подчеркивания и тире, это выглядит следующим образом: [a-zA-z0-9.-]+\@[a-zA-z0-9.-]+.[a-zA-Z]+ . Это позволит проверять довольно глупый адрес электронной почты, например tom_anderson.1-neo@my-mail_matrix.com .

 /(?![[:alnum:]]|@|-|_|\.)./ 

В настоящее время, если вы используете форму HTML5 с type=email вы уже на 80% безопасны, так как у браузеров есть свой валидатор. В дополнение к этому добавьте это регулярное выражение к вашему preg_match_all() и отрицайте его:

 if (!preg_match_all("/(?![[:alnum:]]|@|-|_|\.)./",$email)) { .. } 

Найти регулярное выражение, используемое форматами HTML5 для проверки
https://regex101.com/r/mPEKmy/1

Во время выполнения некоторых тестов этим утром я обнаружил, что FILTER_VALIDATE_EMAIL будет проверять myname@domain.com.com как действительный адрес электронной почты.

 $counter = 0; foreach($emails as $email){ $email = trim($email); if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { unset($emails[$counter]); } $counter++; } не $counter = 0; foreach($emails as $email){ $email = trim($email); if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { unset($emails[$counter]); } $counter++; } 

У кого-нибудь есть рекомендация об этом?