Отправка писем с веб-страницы с использованием почтового клиента посетителя
Наиболее простым способом отправки почты с веб-страницы является включение в страницу ссылки типа:
<a href="mailto:имя@mail.ru">Написать письмо</a>
При нажатии на такую ссылку, автоматически открывается почтовая программа, выбранная посетителем по умолчанию, где он, в привычных для себя условиях может написать и отправить письмо (смотрите документацию по HTML). Но предоставление посетителю возможности написать и отправить письмо ни всегда является именно тем, что требуется. Иногда страница должна сама посылать письма, без участия почтовых клиентов и, даже, без ведома посетителя, например, сообщая разработчику о регистрации нового участника форума. В таких случаях требуется использование серверных почтовых программ и серверных скриптов. Наиболее легкими в настройке являются PHP-скрипты, и приводимые ниже скрипты будут написаны на PHP.
Отправка писем с веб-страницы с использованием серверных скриптов
PHP команда (функция) «mail»
Команда (функция) отправки письма на PHP выглядит так:
mail(куда,тема,текст,заголовок);
Первые три параметра команды (куда, тема, текст) обязательны. Это могут быть нормальные человеческие слова, заключенные в кавычки или заранее определенные PHP-переменные, предваряемые знаком доллара. Если параметр не требуется, вместо него нужно поставить две кавычки. Например:
mail("vasia@mail.ru","Test","");
Если кавычки не поставить, посетитель может получить сообщение об ошибке, а письмо может не уйти (зависит от конфигурации сервера).
Параметр ТЕКСТ определяет содержимое письма. Оно может быть заключено в переменную или быть непосредственно введено в команду. Может состоять из комбинации переменных и текста; комбинация символов \r\n служит для инициализации новой строки в получаемом письме:
mail("vasia@mail.ru","Test","$date\r\nВерсия PHP ". phpversion() . "\r\nЭто мое первое письмо!");
Данная функция отправит на адрес vasia@mail.ru письмо с темой «Test» и текстом, состоящим из трех строк:
Значение PHP-переменной date,
Результатом выполнения команды phpversion(),
Фразы «Это мое первое письмо!»
Для тех, кто не знаком с PHP, поясню: переменные в PHP интерпретируются, если заключены в двойные, НО НЕ В ОДИНАРНЫЕ! кавычки, точка является оператором слияния строк.
Необязательный четвертый параметр функции PHP mail содержит заголовок, помещаемый в письме перед текстом. Обычно в нем указывается кодировка письма и обратный адрес. Например:
В данном примере тема письма «Тестовое письмо» написано на русском языке, в результате чего некоторые почтовые клиенты могут отобразить тему некорректно. Эта проблема решается путем кодирования темы:
(косая черта перед кавычками в "\nContent-type: text/plain; charset=\"windows-1251\"" позволяет игнорировать кавычки и вставить их в текст письма, как они есть, не пытаясь интерпретировать как конец параметра. Последняя кавычка не предотвращается косой, так как это действительно конец).
Вызов PHP-кода с WEB-страницы
Существует несколько способов заставить работать PHP-скрипт:
1) Дать странице расширение PHP, например, my-mail.php.
2) Включить вызов PHP-скрипта в гиперссылку html-файла, например:
<A HREF="my-mail.php">отправить письмо</a>
или установить PHP-страницу адресатом для формы (форму можно поместить в сам PHP-файл тогда имя скрипта можно заменить командой <?=$_SERVER["SCRIPT_NAME"]?> интерпретация которой и даст имя текущего PHP-файла):
<FORM name="frm" ACTION="<?=$_SERVER["SCRIPT_NAME"]?>">
<P>Введите E-mail адрес, на который Вы хотите получить письмо:
<P><INPUT TYPE=text SIZE=30 name="to">
<dt><INPUT TYPE=RESET VALUE="Очистить"> <INPUT TYPE=SUBMIT name="doSend" VALUE="Отправить">
</FORM>
(не многим отличается от вызова почтового клиента посетителя).
3) Включить PHP-скрипт в HTML-страницу с помощью SSI:
(смотрите документацию по SSI-директивам). Последний вариант вызывает скрипт без участия посетителя и, в качестве параметров, после вопросительного знака может передать несколько пар переменная=значение, разделенных коммерческим и «&».
Проверка успешности отправки письма
Для проверки успешности отправки письма достаточно задать команду его отправки условием оператора IF:
if(mail($to,$subject,$file,$header))
{
/* Письмо отправлено */
} else {
/* Произошла ошибка */
}
(текст между /* и */ является комментарием и не обрабатывается интерпретатором PHP).
Проверка заполнения полей формы
Для проверки, заполнены ли необходимые поля формы, в тег формы достаточно поставить Ява-скрипт, вызываемый по событию onsubmit (нажатие кнопки «послать») и отменяющий отправку, в случае некорректности данных. Например:
<FORM name="frm" onsubmit="if(document.frm.to.value=='') {alert('Укажите свой E-Mail!'); return false;}" ACTION="my-mail.php">
Использование параметров вызова PHP-кода
Переменные, заданные в форме или переданные в качестве SSI-директивы include (include virtual), могут непосредственно использоваться в PHP-скрипте. Достаточно поставить перед ними знак доллара. Например:
<FORM name="frm" ACTION="<?=$_SERVER["SCRIPT_NAME"]?>">
<P>Введите E-mail адрес, на который Вы хотите получить письмо:
<P><INPUT TYPE=text SIZE=30 name="to">
<dt><INPUT TYPE=RESET VALUE="Очистить"> <INPUT TYPE=SUBMIT name="doSend" VALUE="Отправить">
</FORM>
<?
if(@$doSend) /* Проверить нажатие кнопки, иначе письмо будет уходить и при обновлении страницы (знак @ позволяет отключить сообщение об ошибке, если переменная doSend еще не определена) */
{
$header="From: my@mail.ru\nReply-To: my@mail.ru";
$header.="\nContent-type: text/plain; charset=\"windows-1251\"";
mail($to,"Тест","",$header);
}
?>
Символы <? и ?> означают начало и конец PHP-скрипта.
Использование текста, хранящегося в отдельном файле
Иногда может потребоваться рассылать посетителям некий готовый текст (например, инструкции), или отсылать себе серверные протоколы. Для этого необходимо создать текст сообщения из имеющегося файла, для чего открыть его и считать в тело письма:
$file=fopen("имя_файла","r");
$text=fread($file, filesize("имя_файла")); /* переменная text будет содержать текст из желаемого файла */
fclose($file);
mail($to,"Эксперимент по отправке письмом текста из файла с помощью PHP",$text,$header);
В результате, к получателю придет обычное текстовое сообщение (без каких-либо прикрепленных файлов), содержащее все, что содержалось в указанном файле. При необходимости, к тексту файла можно добавить другие строки, например:
mail($to,"Другой эксперимент по отправке письма PHP mail","$date\r\n$text",$header);
Если файл с текстом, включаемым в письмо, содержит HTML-форматирование, письмо будет выглядеть как исходный HTML-код. Для того чтобы адресату было доставлено нормальное HTML-письмо, требуется иной подход.
Отправка простых HTML-писем с использованием PHP mail
Создание HTML-писем является проблемой, решение которой неизвестно новичкам. На самом деле все очень просто: достаточно в заголовке указать Content-type=text/html, а само письмо записать в html-виде. Например:
$header="From: my@mail.ru\nReply-To: my@mail.ru";
$header.="\nContent-type: text/html; charset=\"windows-1251\"";
$text="<HTML>\r\n";
$text.="<HEAD>\r\n";
$text.="<META http-equiv=Content-Type content='text/html; charset=windows-1251'>\r\n";
$text.="</HEAD>\r\n";
$text.="<BODY>\r\n";
$text.="<h1>Письмо в HTML-формате</h1>\r\n";
$text.="<p>Это обычный абзац (в отличие от предыдущего заголовка 1-го уровня).\r\n";
$text.="</BODY>\r\n";
$text.="</HTML>";
mail($to,"Тест",$text,$header);
В данный HTML-текст нельзя включать рисунки и другие объекты, так как они не будут отправлены вместе с письмом, если их не приаттачить (присоединить к письму).
Отправка письма с аттачем (вложением) с использованием PHP mail
Для PHP-кода не имеет значения сколько файлов нужно приаттачить. Разница лиш в том, сколько раз требуется повторить код обработки. Поэтому сразу рассмотрим вариант с неопределенным количеством вложений. Данный код можно сохранить в отдельном файле и вызывать из различных форм. В этом случае, его первую строку следует удалить, а переменную $filestring задавать в качестве параметра, передаваемого из формы. Например так:
<FORM name="frm" ACTION="<?=$_SERVER["SCRIPT_NAME"]?>">
<P>Введите E-mail адрес, на который Вы хотите получить письмо:
<P><INPUT TYPE=text SIZE=30 name="to">
<INPUT TYPE=hidden name=filestring VALUE="файл1,файл2,файл3,и т. д.">
<INPUT TYPE=SUBMIT name="doSend" VALUE="Отправить">
</FORM>
Сам скрипт, создающий письмо с аттачем, выглядит так (предпологается что переменная filestring должна определятся в самом скрипте, а не передаваться извне):
$filestring="файл1,файл2,файл3,и т. д."; /* поместить в строку перечень присоединяемых файлов */
$filearr=split(",", $filestring); /* разбить перечень файлов на элементы массива, ориентируясь по запятой */
$boundary="------"; /* задать разделитель файлов */
$header="From: my@mail.ru\nReply-To: my@mail.ru\n";
$header.="Content-Type: multipart/mixed; boundary=\"$boundary\"";
$body=""; /* объявить глобальную переменную body */
function attach($name) { /* функция обработает каждый файл */
GLOBAL $boundary,$body; /* определить что, эти переменные берутся из глобальных (ранее определенных), а не создаются локально (фишка PHP) */
$file=fopen($name,"r"); /* открыть файл */
$text=fread($file, filesize($name)); /* считать весь в переменную */
fclose($file); /* закрыть */
$body.="--$boundary\n"; /* добавление двух дефисов ОБЯЗАТЕЛЬНО! */
$body.="Content-Type: application/octet-stream; name==?windows-1251?B?". base64_encode($name). "?=\n";
$body.="Content-Transfer-Encoding: base64\n";
$body.="Content-Disposition: attachment; filename==?windows-1251?B?". base64_encode($name). "?=\n\n";
$body.=chunk_split(base64_encode($text))."\n"; /* закодировать полученное из файла и добавить в тело письма */
}
for ($i=0; $i < sizeof($filearr); $i++) /* для переменной i, равной нолю, каждый раз увеличивая на единицу, пока ее значение не сравняется с числом элементов массива */
{
attach($filearr[$i]); /* для каждого элемента массива (каждого файла) вызвать функцию обработки */
}
$body.="--".$boundary ."--\n"; /* добавление двух дефисов ДО и ПОСЛЕ для закрывающего разделителя ОБЯЗАТЕЛЬНО! */
mail("vasia@mail.ru","test",$body,$header);
Правда, HTML-письмо все равно не отобразит рисунки. Для отображения рисунков внутри HTML-письма, требуется
Этот же идентификотор следует указать в качестве имени рисунка с обязательными параметрами 3D"cid:
<img src=3D"cid:Этот же идентификатор>"
В результате, функция должна запускаться со вторым парамертом, указывающим, требуется ли Content-Disposition для данного файла или Content-ID и, в зависимости от значения этого параметра, включать в $body либо одну, либо другую, строку...
Но и это не все! Если к письму аттачатся файлы, его текст нельзя просто поместить под заголовком. Текст письма тоже должен идти, как аттач! Только с другим типом и кодировкой: