БлогNot. PHP: программная отправка письма с вложением

PHP: программная отправка письма с вложением

Сама по себе задача программной отправки E-mail несложна, проблемы обычно бывают с правильным (или относительно правильным) формированием заголовков при передаче в письме вложений. Показанный ниже код с отправкой вложения успешно справился, проверено на реальном сервере. Код не продуман в плане безопасной обработки данных пользователя и приведён в учебных целях.

Предположим, что в некотором скрипте находится форма с полями Email, Subject, Message и File - соответственно, адрес отправителя, тема письма, текст письма и стандартное поле для загрузки файла. В простейшем случае и без дизайна форма будет такой:

<form action="simple_mail.php" enctype="multipart/form-data" method="post">
<div>
 <label for="email"><strong>Email:</strong></label>
 <input type="text" size="50" name="mail_to" id="email" value="" />
</div>
<div>
 <label for="subject"><strong>Subject:</strong></label>
 <input type="text" size="50" name="subject" id="subject" value="" />
</div>
<div>
 <label for="message"><strong>Message:</strong></label>
 <textarea rows="5" cols="50" name="message" id="message"></textarea>
</div>
<div>		
 <input type="file" name="mail_file" /> 
</div>
<input type="submit" value="Send" />
</form>

Получателем данных здесь указан скрипт с именем simple_mail.php, который и выполнит всю работу. Ниже приводится полный листинг простейшего варианта такого скрипта, его достаточно последовательно скопировать и заключить в тег <?php ... ?>

Сначала проверим, что передан допустимый адрес E-mail получателя:

if(empty($_POST['mail_to'])) exit("Введите адрес получателя"); 
 // проверяем правильности заполнения с помощью регулярного выражения 
if (!preg_match("/^[0-9a-z_\-]+@[0-9a-z_\-^\.]+\.[a-z]{2,4}$/i", $_POST['mail_to'])) 
 exit("Введите адрес в виде somebody@server.com");

Проверка валидности адреса E-mail здесь весьма примитивна, можно сделать намного лучше.

Теперь определим, был ли загружен с письмом файл и прочитаем данные остальных полей формы, в реальном скрипте следовало бы обработать данные, полученные методом POST.

$picture = ""; 
 // Если поле выбора вложения не пустое - закачиваем его на сервер 
 if (!empty($_FILES['mail_file']['tmp_name'])) { // Закачиваем файл 
  $path = $_FILES['mail_file']['name']; 
  if (copy($_FILES['mail_file']['tmp_name'], $path)) $picture = $path; 
 } 
 $thm = $_POST['subject']; //Тема письма
 $msg = $_POST['message']; //Текст сообщения
 $mail_to = $_POST['mail_to']; //Адрес получателя

Осталось отправить письмо.

// Отправляем почтовое сообщение 
 if(empty($picture)) mail($mail_to, $thm, $msg); 
 else send_mail($mail_to, $thm, $msg, $picture);

Функцию send_mail, формирующую заголовки письма с вложением и вызывающую стандартную mail, конечно же, нужно написать:

function send_mail($mail_to, $thema, $msg, $path) { 
 // Вспомогательная функция для отправки почтового сообщения с вложением
 // Параметры - адрес получателя, тема письма, текст письма, путь к загруженному файлу
 if ($path) {  
  $fp = fopen($path,"rb");   
  if (!$fp) { print "Cannot open file"; exit(); }   
  $file = fread($fp, filesize($path));   
  fclose($fp);   
 }  
 $name = basename($path); // в этой переменной надо сформировать имя файла (без пути)  
 $EOL = "\r\n"; // ограничитель строк, некоторые почтовые сервера требуют \n - подобрать опытным путём
 $boundary     = "--".md5(uniqid(time()));  // любая строка, которой не будет ниже в потоке данных.  
 $headers    = "MIME-Version: 1.0;$EOL";   
 $headers   .= "Content-Type: multipart/mixed; boundary=\"$boundary\"$EOL";  
 $headers   .= "From: admin@mail.com";  
 $multipart  = "--$boundary$EOL";
 $multipart .= "------------".$bondary."\nContent-Type:text/html;\n";
 $multipart .= "Content-Transfer-Encoding: 8bit\n\n$msg\n\n";
 $multipart .= $EOL; // раздел между заголовками и телом html-части 
 $multipart .=  "$EOL--$boundary$EOL";   
 $multipart .= "Content-Type: application/octet-stream; name=\"$name\"$EOL";   
 $multipart .= "Content-Transfer-Encoding: base64$EOL";   
 $multipart .= "Content-Disposition: attachment; filename=\"$name\"$EOL";   
 $multipart .= $EOL; // раздел между заголовками и телом прикрепленного файла 
 $multipart .= chunk_split(base64_encode($file));   
 $multipart .= "$EOL--$boundary--$EOL";   
 if (!mail($mail_to, $thema, $multipart, $headers)) { //если не письмо не отправлено
  return false;           
 }  
 else { // если письмо отправлено
  return true;  
 }  
 exit;  
}

Здесь письмо приходит с адреса admin@mail.com, можно поставить вместо него другой адрес. Неплохо также после вызова функции (или её последним оператором) удалить ненужный больше на сервере файл $path.

28.04.2012, 12:26 [28362 просмотра]


теги: php программирование email

показать комментарии (1)