PHP sendmail: отправка почты с вложениями посредством PHP
В этой статье хочу поведать Вам о том, как отправлять почту с вложениями стандартными средствами PHP, не прибегая к PEAR и подобным библиотекам.
Начнем с азов. Отправка почты в php выполняется с помощью функции mail:
bool mail ( string $to, string $subject, string $message [, string $additional_headers [, string $additional_parameters]] )
to - адрес получателя subject - тема письма message - текст письма Далее слудуют необязательные параметры: additional_headers - дополнительные заголовки additional_parameters - дополнительные параметры командной строки Возвращаемое значение: true - письмо принято к доставке false - письмо не принято к доставке
В простейшем виде это выглядит так:
<?php
if (mail('test@example.com', 'Письмо из скрипта', 'Привет, Василий! Как дела?')){
echo 'Письмо успешно отправлено!';
}else{
echo 'При отправке письма возникла ошибка';
}
?>
Если результатом работы вышепреведенного скрипта будет ошибка, значит в вашей сборке PHP нет поддержки mail, советую обратиться к администратору.
Теперь разберёмся с дополнительными заголовками. Что вообще такое, заголовок письма? Это, согласно стандарту RFC-822, одна из частей электронного письма. То есть, письмо состоит из заголовков и тела (также и из "конверта", но это нам сейчас не нужно). Заголовок всегда находится перед телом и отделен от него пустой строкой. Заголовок состоит из имени и содержания, разделённых двоеточием. Между собой заголовки разделяются так: каждый заголовок начинается с новой строки. Но, лучше смотреть на примере:
Date: Fri, 4 Jun 2010 16:12:00 From: sales@example.com To: ivan@example.com Reply-to: sales@example.com Subject: Ваш заказ принят X-Mailer: php script
Следовательно, чтобы, к примеру, установить произвольную дату письма, или установить адрес отправителя, необходимо указать заголовки (по умолчанию, дата задаётся текущая, а тема устанавливается во втором параметре)
<?php
if (mail('test@example.com', 'Письмо из скрипта', 'Привет Василий, как дела?', 'From: ivan@example.com')){
echo 'Письмо успешно отправлено!';
}else{
echo 'При отправке письма возникла ошибка';
}
?>
Отправка письма в HTML-формате
Большинству задач вышеприведённого скрипта отправки mail`ов хватает, но мы пойдём дальше, и научимся отправлять письма в HTML-формате. В этом также нет ничего сложного:
<?php
if (mail('test@example.com',
'Письмо из скрипта',
'<html><head><title>Вася, привет</title></head><body bgcolor="#feeffe"><font color="blue">Привет Василий, как дела?</font><br /><font color="green">Я умею отправлять письма с помощью php! И скоро научусь отправлять письма с помощью php с вложениями! Это будет круто!</font></body></html>',
"From: ivan@example.com\r\n
Content-type: text/html; charset=utf-8\r\n
X-Mailer: PHP mail script"
))
{
echo 'Письмо успешно отправлено!';
}else{
echo 'При отправке письма возникла ошибка';
}
?>
Обратите внимание! После каждого заголовка стоит конструкция \r\n — это так обозначается перенос строки. А тот перенос, что вы видите — это обычное выравнивание, дабы удобно было читать код. Т.е. смело можно написать так:
...mail('test@example.com', 'Письмо из скрипта', '(аштиэмэль...)', "From: ivan@example.com\r\nContent-type: text/html; charset=utf-8\r\nX-Mailer: PHP mail script")...
И ещё обратите внимание на то, что escape-последовательности (а именно так называются конструкции вида \r\n) работают только с двойными кавычками!
Что же нового в этом скрипте? Ну, во-первых, мы в заголовках указали тип содержимого (HTML) и кодировку. Во-вторых, просто в теле написали нужный нам html-код. Всё просто!
Отправка писем с вложениями
Вот мы вплотную подошли к отправке писем на php с вложениями.
<?php
$un = strtoupper(uniqid(time()));
$file = file_get_contents('file.zip');
if (mail('test@example.com',
'Письмо из скрипта',
//тело
"------------".$un."\r\n\r\n
Content-Type:text/plain; charset=utf-8\r\n
Content-Transfer-Encoding: 8bit\r\n\r\n
Привет Василий, посмотри вложение\r\n\r\n
------------".$un."\r\n\r\n
Content-Type: application/octet-stream;name=\"file.zip\"\r\n\r\n
Content-Transfer-Encoding:base64\r\n
Content-Disposition:attachment;filename="file.zip"\r\n\r\n
".chunk_split(base64_encode($file))."\r\n
",
//заголовки
"From: ivan@example.com\r\n
MIME-Version: 1.0\r\n
Content-Type: multipart/alternative;boundary=\"----------".$un."\"\r\n
"
))
{
echo 'Письмо успешно отправлено!';
}else{
echo 'При отправке письма возникла ошибка';
}
?>
Всё сложно? Неправда, давайте разбираться. Для начала, мы создали уникальный идентификатор $un, с его помощью мы сможем разделять между собой вложенные файлы, а также тело письма. Далее, мы читаем содержимое подключаемого файла и заносим его в переменную $file.
Но как происходит отправка? В заголовках мы указываем тип содержимого и наш уникальный разделитель (Content-Type: multipart/alternative;boundary=\"----------".$un."\"). А в теле письма, разделяя разделителем, пишем сначала текст, потом вложенный файл:
"------------".$un."\r\n\r\n Content-Type:text/plain; charset=utf-8\r\n Content-Transfer-Encoding: 8bit\r\n\r\n Привет Василий, посмотри вложение\r\n\r\n ------------".$un."\r\n Content-Type: application/octet-stream;name=\"file.zip\"\r\n\r\n Content-Transfer-Encoding:base64\r\n Content-Disposition:attachment;filename=\"file.zip\"\r\n\r\n ".chunk_split(base64_encode($file))
Пишем, естественно, с указанием типа содержимого (Content-Type) и типа конвертации (Content-Transfer-Encoding).
chunk_split(base64_encode($file)) — это и есть вложение нашего файла (помните, мы в переменную $file внесли содержимое?), предварительно его конвертировав в base64
Готовая функция отправки почты с вложением
Если терпеливый читатель дочитал до этого места, то вот универсальная функция отправки почты с вложением:
function KMail($to, $from, $subj, $text, $files = null, $isHTML = false){
$boundary = "------------".strtoupper(md5(uniqid(rand())));
$headers = "From: ".$from."\r\n
X-Mailer: koz1024.net\r\n
MIME-Version: 1.0\r\n
Content-Type: multipart/alternative;boundary=\"$boundary\"\r\n\r\n
";
if (!$isHTML){
$type = 'text/plain';
}else{
$type = 'text/html';
}
$body = $boundary."\r\n\r\n
Content-Type:".$type."; charset=utf-8\r\n
Content-Transfer-Encoding: 8bit\r\n\r\n
".$text."\r\n\r\n";
if ((is_array($files))&&(!empty($files))){
foreach($files as $filename => $filecontent){
$body .= $boundary."\r\n
Content-Type: application/octet-stream;name=\"".$filename."\"\r\n
Content-Transfer-Encoding:base64\r\n
Content-Disposition:attachment;filename=\"".$filename."\"\r\n\r\n
".chunk_split(base64_encode($filecontent));
}
}
return mail($to, $subj, $body, $headers);
}
Использование:
$files = array('archive.zip' => file_get_contents('archive.zip'), 'myphoto.png' => file_get_contents('myfoto.png'));
if (KMail('test@example.com', 'ivan@example.com', 'проба пера', 'Привет, высылаю файлы...', $files, false)){
echo 'Mail Отправлен';
}else{
echo 'Произошла ошибка';
}
//или так
$html = "(HTML код письма)";
if (KMail('test@example.com', 'ivan@example.com', 'проба пера', $html, null, true)){
echo 'Mail Отправлен';
}else{
echo 'Произошла ошибка';
}
С полученными знаниями, Вы без труда разберетесь в работе этой функции. Надеюсь, она Вам пригодится!
Отправка письма в HTML формате с картинками
Хотел написать этот раздел сразу после "Отправки письма в HTML-формате", и это было бы логично. Но. Раздел бы получился очень громоздким, а пользуясь функцией, которую я описал выше, можно легко передавать письма в формате HTML да ещё и с картинками. Скажу лишь о том, что сами картинки должны являтся частью html кода, а вместо ссылок на них — использоваться cid - идентификаторы
Вот мы и разобрали, как с помощью простого php отправлять e-mail`ы, отправлять в HTML-формате, отправлять с вложениями. Удачи!
Предыдущая статья: cURL для начинающих. Пишем парсер Следующая статья: Аякс загрузка файлов







Комментарии:
| Следующая страница »
AntonMMF 25.08.2010 10:09
"Готовая функция отправки почты с вложением" Файл не прикрепляется к письму в виде файла, а идёт в теле письма в виде текста
koz1024 01.09.2010 18:30
AntonMMF, и все, кто использует функцию: чтобы не выводился файл в теле письма, уберите двойные переносы строк "\r\n\r\n" (замените на одинарные) и попробуйте написать все заголовки в одну строку и всё тело в одну строку Я, к сожалению, сейчас не могу, но позже обязательно подправлю это в статье, покажу как надо. AntonMMF, спасибо, что заметили!
NurMKM 25.10.2010 09:43
Спасибо большое!!!
iham 31.10.2010 23:17
Очень вовремя ) Спасибо.
nezabudka 12.11.2010 22:08
Спасибо за скрипт. Но у меня почему то письмо на почту не приходит...
koz1024 15.11.2010 03:15
nezabudka, причин может быть много: от настроек сервера, до пропущеной запятой; нужно смотреть, разбираться, что в конкретном Вашем случае
VLOmper 25.01.2011 02:57
"а вместо ссылок на них — использоваться cid - идентификаторы" Это как понять? простой адрес на картинку? или что? Если можно пример пожалуйста.
Лешка 28.01.2011 22:50
Content-Type самого письма должен быть multipart/mixed, а не alternative. Alternative используется, когда письмо содержит несколько разных представлений одного и того же. Например, почтовые клиенты при отправки HTML-писем часто включают обычную текстовую версию того же письма. Для этого используется сообщение в типом multipart/alternative, и дальше части с типами text/plain, text/html. Почтовый клиент на принимающей стороне, понимающий HTML, покажет содержимое с типом text/html, а если окажется, что почтовая программа старая и не понимает HTML (или пользователь выключил), то будет использоваться часть с типом text/plain.
jj 30.01.2011 11:00
Интересно, но система учитывает только первый заголовок из "From: ivan@example.com\r\n Content-type: text/html; charset=utf-8\r\n X-Mailer: PHP mail script" И не важно, какой именно параметр ставить первым. По примеру корректно выставляется "from", но формат письма текстовый
Sphehr 22.02.2011 00:12
Вот альтернативаня реализация. У меня проверено - работает. http://www.finalwebsites.com/forums/topic/php-e-mail-attachment-script
Комментарии:
| Следующая страница »