создание и разработка веб-сайтов
поисковая оптимизация и реклама
статьи о программировании и веб-дизайне

Ссылки по теме:
 

Отправляем почту с вложениями

В свое время была у меня задача сделать форму отправки письма с сайта при помощи php-скрипта. Задача сама по себе простая, как мы убедились в предыдущей статье. Используем функцию mail(), передаем ей адрес назначения, тему письма, тело письма, формируем заголовки и отправлем преспокойненько получателю. Однако достижение цели омрачалось необходимостью передавать вместе с письмом вложения в виде графического файла. А вот вопрос как приаттачить файл к письму с помощью php, тогда вызвал у меня затруднения, в результате чего пришлось изучать почтовые стандарты RFC. Задача отняла у меня довольно много времени, хотя ничего особо сложного в ней не было, но в итоге я ее решил и сегодня мы как раз разберем пример реализации функции mail() с возможностью отправки файлов. Так как почтовые вложения передаются в теле заголовков, то не лишним будет уделить несколько слов расширению почтового стандарта MIME (RFC1521), который позволяет размечать письмо на части отдельных типов, для дальнейшей пересылки его получателю.
Для начала посмотрим на примере какими сообщениями обмениваются почтовые сервера:

From:yourmail@yourdomen.xxx To:mymail@mydomen.xxx Subject:Пример MIME-Version: 1.0 Content-Type:multipart/mixed; boundary="unique-boundary" То что здесь будет игнорироваться почтовой программой --unique-boundary Content-Type:text/html; charset=windows-1251 <p>текст с гипертекстовой разметкой</p> --unique-boundary Content-Type:image/jpeg; name="file.jpg" Content-Transfer-Encoding:base64 Кодированное в base64 графическое изображение --unique-boundary-- То что здесь будет игнорироваться почтовой программой Собственно, в этом запросе уже есть все что нам нужно, строка Content-Type:text/html; charset=windows-1251 Производит отправку текста письма в гипертекстовой разметке, а строка Content-Type:image/jpeg; name="file.jpg" Content-Transfer-Encoding:base64 Пересылает перекодированое в специальных символах base64 «приаттаченное» изображение. Еще на одной особенности необходимо заострить особое внимание. Вы наверное заметили, что в теле сообщения имеется уникальная граница «unique-boundary», которая призвана размечать различные части письма и отделять типы частей одну от другой. Любая граница предваряется двумя дефисами «--» и самая последняя граница закрывается также двумя дефисами «--». Вот собственно и все премудрости.

Как видите ничего сложного в отправке сообщений нет, нам осталось только написать, показанный выше запрос на PHP. Чтобы было удобно и быстро вызвать функцию отправки почты с вложениями и без, мы напишем свой класс x_mail, который поместим в файл x_mail.php файл x_mail.php <?php class x_mail{ #Задаем переменные public $from; public $to; public $headers; public $subject; public $message; private $items; #функция отправки почты public function sendmail(){ $_headers=""; if(!empty($this->from)){$_headers.="From: ".$this->from. "\n";} if(!empty($this->headers)){$_headers.=$this->headers. "\n";} if(!empty($this->message)){ $this->__attachmentsArray($this->message,"","text/plain");} $_headers.="MIME-Version: 1.0\n"; $_headers.=$this->__insertAttachments(); mail($this->to,$this->subject,"",$_headers); } #Инициализация переменных класса public function x_mail(){ $this->from = ""; $this->to = ""; $this->headers = ""; $this->subject = ""; $this->message = ""; $this->items = array(); } #формируем массив вложений public function __attachmentsArray($body,$name="",$type="application/octet-stream"){ $this->items[]=array("body" => base64_encode($body), "name" => $name,"type" => $type,"encoding" => "base64"); } #функция добавляет файлы в тело письма private function __insertAttachments(){ $bound = "bound".md5(time()); $multipart = "Content-Type: multipart/mixed; boundary = \"$bound\"\n\nThis is a MIME message.\n\n--$bound"; for($i = sizeof($this->items)-1; $i>=0; $i--) { $multipart .= "\n".$this->__mimeConstructor($this->items[$i]). "--$bound";} return $multipart.= "--\n"; } #формируем MIME-тип вложения private function __mimeConstructor($items) { $_mC="Content-Type: ".$items["type"].($items["name"]? "; name = \"". $items["name"]."\"" : "")."\nContent-Transfer-Encoding: ". $items["encoding"]."\n\n".$items["body"]."\n"; return $_mC; } } ?> Для того, чтобы воспользоваться классом создадим файл sendmail.php <?php $attachment=array(); include('x_mail.php'); #загружаем файлы в массив $attachment["file1.jpg"] = fread(fopen("file1.jpg", "r"), filesize("file1.jpg")); $attachment["file2.jpg"] = fread(fopen("file2.jpg", "r"), filesize("file2.jpg")); #создаем переменную класса x_mail() $mail = new x_mail(); #задаем переменные для отправки почты $mail->from = "info@yourdomen.com"; $mail->to = "info@mydomen.com"; $mail->subject = "Доставка файла"; $mail->message = "Вам доставлен файл!"; #прикрепляем вложения foreach($attachment as $k=>$v) {$mail->__attachmentsArray($v, $k);}; #Отправляем письмо $mail->sendmail(); ?>


23 апреля 2009