У меня есть класс, который проверяет каждый вход, прежде чем я отправлю его на уровень базы данных. Обратите внимание, что моя проблема заключается не в побеге, а в чем-либо. Мой уровень базы данных будет обрабатывать проблему SQL Injection. Все, что я хочу сделать, это проверить, является ли сообщение действительным или нет, потому что позже этот адрес электронной почты может использоваться как «отправить». Например, пользователь восстановит доступ к своей учетной записи через ссылку, отправленную по электронной почте. Я много читал о filter_var
и есть куча людей, которые против этого, и другая группа в пользу. Уделение особого внимания «Я просто хочу проверить электронную почту, а не фильтровать ее для базы данных или для html или XSS или что-то еще», есть ли проблема с использованием filter_var
?
Да, ты должен.
Использование стандартной проверки библиотек вместо домашнего пива имеет несколько преимуществ:
Однако проверка формата адреса электронной почты – это только первая линия защиты, если вы действительно хотите знать, что это реально или нет, вам нужно будет отправить ей сообщение.
Да, вы должны использовать 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
отдельности (что является idn_to_ascii
а не очевидным).
Это делает filter_var
довольно бесполезным, на мой взгляд: чем больше адресов электронной почты unicode появляется в дикой природе, тем более законные адреса электронной почты будут терпеть неудачу, что особенно характерно для таких стран, как Китай или Бразилия, где существует очевидный спрос на эти адреса. filter_var
также не разрешает адреса электронной почты, такие как root@localhost
, которые действительны и могут быть полезны в контексте сервера.
Было бы очень полезно, если бы библиотека электронной почты существовала для проверки в соответствии с конкретными инструкциями – разрешены ли только доменные имена, а также произвольные хосты, такие как localhost, или есть ли белый список для пользовательских доменов, который должен быть действительным? Должен ли разрешаться unicode? Каковы распространенные опечатки для доменных имен freemail (например, @ homail.com), которые также должны потерпеть неудачу?
Кроме того, проверка некоторых доменных имен более конкретным образом была бы разумной – hotmail.com не разрешает символы unicode на данный момент и имеет определенные ограничения на используемые символы. Поскольку большинство используемых адресов электронной почты в приложениях PHP сосредоточены на возможно более чем 100 различных доменах, это может быть использовано для более точного подтверждения этих доменных имен. К сожалению, пока нет такой библиотеки, насколько я знаю.
Некоторые из комментариев, которые я видел, не соответствовали моему тестированию, поэтому я хотел указать на функциональность, которую я нашел с помощью 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', '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