Освой программирование играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Отправка письма средствами PHP

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

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

Адрес электронной почты отправителя - в форме у нас есть поле <input type="text" name="email" id="email">, в котором пользователь должен ввести свой адрес.

Адрес электронной почты получателя - это ваш электронный адрес, уж его вы знаете.

Тема письма - можем придумать сами. Проявите фантазию.

Само письмо - в принципе мы можем использовать тот же текст, который выводился в сценарии report.php. Только его нужно отформатировать немного, чтобы получить нужную строку. Ведь, как вы помните, в сценарии мы выводили текст в отдельных строках при помощи команды echo с использованием тега <br> для красивого вывода на html-странице.

Вспоминаем код:


echo 'Спасибо за заполнение формы.<br>';
echo 'Кота похитили ' . $when . '<br>';
echo 'Похитители: ' . $description . '<br>';
echo 'Ваш email: ' . $email;

Создадим новую переменную $msg, которая будет содержать текст письма:


$msg = 'Спасибо за заполнение формы.'.
   'Кота похитили ' . $when .
   'Похитители: ' . $description .
   'Ваш email: ' . $email;

Мы создали достаточно длинную строку, соединив отдельные части с помощью оператора конкатенации (точки). Если вывести текст, содержащий в новой переменной через команду echo $msg; на той странице с сценарием, то получим приблизительно следующее:


Спасибо за заполнение формы.Кота похитили 24.02.1999Похитители: злые птичкиВаш email: [email protected]

Мы получили текст письма, правда выглядит он пока не слишком опрятным. Можно было добавить пробелов между предложениями или разбить на отдельные строчки, но в целом результат нас устраивает.

Так как письмо - это обычный текст, то здесь нельзя использовать HTML-тег <br>. Для перевода текста на новую строку используется символ новой строки в форме Escape-последовательности '\n'.

Попробуем переделать пример:


$msg = 'Спасибо за заполнение формы.\n'.
   'Кота похитили ' . $when . '\n'.
   'Похитители: ' . $description . '\n'.
   'Ваш email: ' . $email;

Снова выводим результат с помощью echo $msg; и смотрим:


Спасибо за заполнение формы.\nКота похитили 24.02.1999\nПохитители: злые птички\nВаш email: [email protected]

Вместо переноса строк мы видим \n как обычный текст, который затесался между нашими словами для письма. Фигня какая-то.

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


$msg = "Спасибо за заполнение формы.\n".
       "Кота похитили  $when\n".
       "Похитители: $description\n".
       "Ваш email: $email";
	   
echo $msg; 	   

Мы видим, что символы \n исчезли, но текст всё равно выводится в одну строку. Однако, если вы откроете исходный код страницы, то увидите, что на самом деле текст разбит на отдельные строки. Но браузер игнорирует подобные переносы, поэтому мы не замечаем эффекта переноса строк. Если бы мы выводили строку в текстовый документ, то всё бы работало, как мы хотели. В письме переносы также будут работать.

Обратите внимание на следующую особенность. В примере с двойными кавычками мы вставляли имена переменных прямо в текст без обрамляющий кавычек. PHP самостоятельно подставляет значения переменных в текст. Это очень удобно. Здесь важно понимать разницу между одинарными и двойными кавычками в PHP-коде. Данное объяснение выходит за рамки изучаемого урока.

У нас есть все необходимые компоненты для отправки письма. Осталось скомпоновать в одно целое. Создадим отдельные переменные для каждого элемента письма:


$email = $_POST['email']; // от кого
$to = "[email protected]"; // кому
$subject = "Вам письмо"; // тема письма
$msg = "Спасибо за заполнение формы.\n".
       "Кота похитили  $when\n".
       "Похитители: $description\n".
       "Ваш email: $email";

В PHP есть встроенная функция для отправки письма mail(). Простой вариант функции выглядит следующим образом:


mail($to, $subject, $msg);

Как видите, в этом варианте не используется электронный адрес отправителя. Остальные параметры являются обязательными. На практике используют другой вариант функции с четырьмя параметрами, где нужно указать электронную почту отправителя. Причем, у четвёртого параметра следует обязательно добавить слово From: (с пробелом). Полностью, функция выглядит так:


mail($to, $subject, $msg, 'From: ' . $email);

Мы соединили слово From: с адресом почты через точку (оператор конкатенации) и получили четвёртый параметр для функции.

Если вы хотите также отправить копию и скрытую копию, то следует добавить нужные элементы ("Cc: " или "Bcc: ") в четвёртом параметре, отделяя элементы комбинацией символов возврата каретки и новой строки, например так:


"From: " . $from . "\r\nCc: " . $cc

При отправке письма вы можете столкнуться с двумя проблемами. Первая - ваш сервер может не поддерживать функцию mail(). Вам следует обратиться к своему хостеру с этим вопросом или сменить хостера и выбрать хостинг с поддержкой отправки писем.

Вторая проблема связана с русским языком. Исторически сложилось, что некоторые служебные заголовки при отправке писем используют устаревшие кодировки. И если вы будете проверять поступившую почту у себя на компьютере, то можете увидеть кракозябры в теме письма, в сообщении, в обратном адресе. Некоторые почтовые сервера умеют частично определять и конвертировать на лету неправильную кодировку. А если вы привыкли читать почту через почтовые клиенты, то эта проблема может проявиться особенно отчётливо.

Вот рабочий пример, который обычно я использую в своих проектах. Для начала формирую кодировку для темы письма следующим образом:


$subject = "=?utf-8?B?" . base64_encode("здесь тема вашего письма") . "?=";

А дальше формируются данные для отправки письма. Пример расчитан на кодировку UTF-8:


mail($to, $subject, $msg, "From: $email\r\nReply-To: $email\r\nReturn-Path: $email\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Transfer-Encoding: 8bit");

Теперь мы умеем создавать форму, получать данные от пользователя и отправлять полученную информацию себе на почту.

Реклама