Валидация электронной почты (email) из данных формы на стороне сервера с помощью php

Для тех, кто решил написать простую (или сложную) программу, получающую данные от пользователя в процессе работы обязательно придётся столкнуться с вопросом валидации данных, введённых пользователем у себя в браузере. Эти данные можно как угодно обрабатывать на стороне клиента, используя навороченные проверки с помощью JavaScript. Но все эти проверки легко обходятся и всегда есть шанс того, что на сервер прилетит не то, что задумано и должно быть заранее проверено на ошибки. В этой статье расскажу, к какому решению по валидации адреса электронной почты (email) я пришёл.



Задача о валидации адреса электронной почты (email) на сервере

В общем случае задача о валидации адреса электронной почты (email) на сервере стоит таким образом, что нужно проверить соответствие полученной строки на соблюдение стандартов. И при ближайшем рассмотрении получается, что email - это не просто куски текста, цифр и определённых спец.символов, разделённых @ и .. После внедрения IDN (Internationalized Domain Names — интернационализованные доменные имена) нужно по-хорошему ещё пытаться переводить полученные данные в Punycode, если вдруг окажется, что пользователь решил завести себе мыло с использованием национального алфавита. При этом нужно учесть ещё тот факт, что есть не просто пользователи и злоумышленники (или просто экспериментаторы), которые могут отправить винегрет ланитицы и кирилицы...

В общем, зарывшись в этот вопрос с головой я решил не влазить в эти дебри, тем более, что они куда более извилисты и тернисты. В итоге решил использовать использовать стандартные средства, предлагаемые разработчиками php. Как только они внесут какие-то доработки в язык программирования, так пользователи моих сервисов смогут использовать то, что в текущей версии для них недоступно. Для тех, кто боится потерять своих пользователей, лучше ищите другое решение. В данном вопросе я решил быть консерватором и не поддаваться тем веяниям моды, которые пока не вошли в стандарт языка. Мне так проще. Как быть с пользователями, которые используют нестандартизованные решения — это на их усмотрение. Хотят получить доступ к моим разработкам — зарегистрируют бесплатный ящик на нормальном почтовом сервисе. Хотят выпендрёжа, — это их право.

Важно!
Повторюсь. То, что прилетело к вам на сервер на вход к скрипту-обработчику данных формы, нужно проверять вне зависимости от того, какими бы проверками вы не увешали форму в браузере пользователя. Все эти проверки легко обходятся и на вход скрипту можно прислать любые кракозяблики. =D

Валидация адреса электронной почты (email) на сервере стандартными средствами php

В php есть встроенная функция фильтрации данных для обработки данных форм. Это функция filter_var(), которая фильтрует переменную с помощью определенного фильтра. У неё есть ряд фильтров, которые можно применять для обработки переменной. Я выбрал две, которые должны обеспечить защиту от злоумышленников и не отсекать пользователей, которые совершают какие-то совсем дурацкие ошибки.

  • Фильтр FILTER_SANITIZE_EMAIL, который удаляет все символы, кроме букв, цифр и !#$%&'*+-=?^_`{|}~@.[]. Использую его именно из-за пробелов, так как был не раз свидетелем того, как пользователи упорно ставили пробелы там, где их не должно быть. Зачем они это делают, так и не получилось выяснить при опросе — работа подсознания не поддаётся логическому анализу. =)
  • Фильтр FILTER_VALIDATE_EMAIL , который проверяет, что значение является корректным e-mail. В целом, происходит проверка синтаксиса адреса в соответствии с RFC 822, за исключением того, что не поддерживаются комментарии, схлопывание пробельных символов и доменные имена без точек.

Программа на php валидации адреса электронной почты (email) на сервере стандартными фильтрами

Собственно, как всё это работает, можно проверить, написав простую программу:

<?php
if (isset($_POST['email'])) {$email = $_POST['email'];} else {$email = '';}
$sanitized_email = filter_var($email, FILTER_SANITIZE_EMAIL);
if (filter_var($sanitized_email, FILTER_VALIDATE_EMAIL)) {
    echo "E-mail адрес <font color=green><b>" . $sanitized_email . "</b></font> указан верно<br>\n";
} else {
    echo "E-mail адрес <font color=red><b>" . $sanitized_email . "</b></font> указан неверно<br>\n";
}
?>

<form method="post" action="">
<input type="text" name="email" placeholder="введите email">
<input class="enter" type="submit" value="Enter!">
</form>

Последние четыре строчки — это HTML-код вывода формы для ввода email'а.

Первая строчка if (isset($_POST['email'])) {$email = $_POST['email'];} else {$email = '';} — проверка на то, что поле email было заполнено. Но, при первом обращении к этому скрипту, поле не заполнено. Поэтому, чтобы не сыпались предупреджения, для этого случая, если переменная $_POST['email'] не задана, принудительно объявляем переменную $email с пустым значением ''. После этого интерпретатор php не будет выдавать никаких сообщений, даже, если включен режим отладки.

Во второй строчке $sanitized_email = filter_var($email, FILTER_SANITIZE_EMAIL); применяем фильтр FILTER_SANITIZE_EMAIL. к прилетевшей переменной $email и записываем отфильтрованное в переменную $sanitized_email.

Ну и проверяем полученную переменную фильтром FILTER_VALIDATE_EMAIL. Если проверка проходит filter_var($sanitized_email, FILTER_VALIDATE_EMAIL), выдаём сообщение, что всё хорошо. Если проверка не проходит — всё плохо.

Резюме

Если нет нужны хранить неотфильтрованную переменную, то код можно упростить до:

<?php
if (isset($_POST['email'])) {$email = $_POST['email'];} else {$email = '';}
$email = filter_var($email, FILTER_SANITIZE_EMAIL);
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "E-mail адрес <font color=green><b>" . $email . "</b></font> указан верно<br>\n";
} else {
    echo "E-mail адрес <font color=red><b>" . $email . "</b></font> указан неверно<br>\n";
}
?>

<form method="post" action="">
<input type="text" name="email" placeholder="введите email">
<input class="enter" type="submit" value="Enter!">
</form>

Просто перепрописав значение переменной $email после применения фильтра: $email = filter_var($email, FILTER_SANITIZE_EMAIL);. Так будет работать наверное чуть быстрее. =)

Таким образом я решил для себя вопрос о том, как сделать валидацию электронной почты (email) из данных формы на стороне сервера с помощью php.

Решает ли это 100% задачи? — Нет!

Но в моём случае этого достаточно.

P.S.

Есть мнение, что валидация email вообще не нужна. Нужно просто послать письмо пользователю на то, что он ввёл с кодом подтверждения. В моём случае — это следующий этап. Но оставлять без проверки того, что прилетело от пользователя в качестве его почты я пока не намерен. Мало ли кто что решит послать на вход моим программам. Да и хранить весь этот хлам в ожидании, пока пользователь (может быть) решит подтвердить свою почту, тоже не хочется. Повторюсь: неадекватные пользователи лично мне не нужны.

Заберите ссылку на статью к себе, чтобы потом легко её найти!
Раз уж досюда дочитали, то может может есть желание рассказать об этом месте своим друзьям, знакомым и просто мимо проходящим?
Не надо себя сдерживать! ;)

Старт! Горячий старт на просторы интернета
Старт! Горячий старт на просторы интернета
Старт! Меню