Действительно ли работает PHP filter_var FILTER_VALIDATE_EMAIL?

После чтения различных сообщений я решил не использовать REGEX для проверки правильности адреса электронной почты и просто использования встроенной функции filter_var PHP. Казалось, что все работает нормально, пока он не начал сообщать мне, что электронное письмо было недействительным, потому что в нем было число.

т.е. name@domain.com работает, а name2@domain.com – нет.

Я что-то упустил, или filter_var($email, FILTER_VALIDATE_EMAIL) действительно неэффективен?

Регулярное выражение, используемое в модуле фильтра PHP 5.3.3, основано на блоге Майкла Раштона о проверке адресов электронной почты . Кажется, это работает для случая, о котором вы упоминаете.

Вы также можете проверить некоторые параметры в сравнении E-mail Address Validating Regular Expressions (регулярное выражение, используемое в настоящее время в PHP, является одним из тестируемых).

Затем вы можете выбрать регулярное выражение, которое вам больше нравится, и использовать его при вызове preg_match() .

Или вы можете взять regexp и заменить файл в файле PHP / ext / filter / logical_filter.c, функцию php_filter_validate_email() и перестроить PHP.

name2@domain.com, похоже, отлично работает: http://codepad.org/5HDgMW5i

Но я определенно видел, как люди жалуются, что у него проблемы, даже на SO. По всей вероятности, у него есть проблемы, но так же будет и регулярное выражение. Спецификации адреса электронной почты очень и очень сложны ( RFC XXXX ).

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

этот фильтр был обновлен в последнее время. http://codepad.org/Lz5m2S2N – появляется, что в версии, используемой кодекадой, ваш случай фильтруется правильно

Вы также можете посмотреть http://bugs.php.net/49576 и http://svn.php.net/viewvc/php/php-src/trunk/ext/filter/logical_filters.c . Regexp довольно страшно.

 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@ba 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 (ie, 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,}'. '(?:(?:[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', $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) - 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@ba 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 (ie, 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,}'. '(?:(?:[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', $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)