В этой статье хочу поведать Вам о том, как отправлять почту с вложениями стандартными средствами 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-формате, отправлять с вложениями. Удачи!