Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

PHP, SQL, SSI-Дневник ламера, превращающегося в ГУРУ :-) Отправка писем с вложением файлов


Информационный Канал Subscribe.Ru

Выпуск номер 10
Рассылка: Дневник Ламера
     
 

Тема: Отправка писем с вложенными файлами

Вчера товарищ спросил, как-же отправлять письма с вложенными в них файлами. У меня лежал скрипт на эту тему, но я его не проверял на работоспособность. Тема вдруг стала нужной поэтому решил разобраться с этим. Работает с использованием класса, поэтому я раскажу как это ПРОСТО РАБОТАЕТ, а ПОЧЕМУ ЭТО РАБОТАЕТ, я и сам в подробностях не разбирался :-)
Тоесть если надо, чтобы просто работало, разбираться особо и не надо в самом описании класса. В этом случае важна самая последняя часть, где описываются функции вызова и передаваемые ей параметры.


// Форма, в которой забиваем данные.

<form name="form1" enctype="multipart/form-data" method="post" action=""> // Поле enctype в данном случае нужно для того, чтобы можно было нормально определять имя файла. Тоесть входящий файл мы имеем в переменной $file1 и $flnumtwo а имена этих файлов при данном методе кодирования находятся в переменных: $file1_name и $flnumtwo_name

From:<br><input name="emailfrom" type="text" id="emailfrom"><br><br> // От кого посылаем
To:<br><input name="emailto" type="text" id="emailto"><br><br> // Кого посылаем :-)))
Theme:<br><input name="subject" type="text" id="subject"><br><br> // Тема письма
Attach Files:<br> // Файлы, которые добавляем в письмо. Изначально был один в скрипте, но я забиваю два на контроль. Чтоб знать, работает - ли.
<input name="file1" type="file" id="file1"><br><br>
<input name="flnumtwo" type="file" id="flnumtwo">
<br><br>
<input type="submit" name="Submit" value="Submit">
</form>

<?
// Объявляем класс, который и будет отправлять письмо

class mime_mail {
var $parts;
var $to;
var $from;
var $headers;
var $subject;
var $body;

function mime_mail() {
$this->parts = array();
$this->to = "";
$this->from = "";
$this->subject = "";
$this->body = "";
$this->headers = "";
}


// Сама функция добавления файлов в тело письма
function add_attachment($message, $name = "", $ctype = "application/octet-stream") {
$this->parts [] = array (
"ctype" => $ctype,
"message" => $message,
// "encode" => $encode,
"name" => $name
);
}


// Построение сообщения
function build_message($part) {
$message = $part["message"];
$message = chunk_split(base64_encode($message));
$encoding = "base64";
return "Content-Type: ".$part["ctype"].($part["name"]? "; name = \"".$part["name"]."\"" : "")."\nContent-Transfer-Encoding: $encoding\n\n$message\n";
}

function build_multipart() {
$boundary = "b".md5(uniqid(time()));
$multipart = "Content-Type: multipart/mixed; boundary = $boundary\n\nThis is a MIME encoded message.\n\n--$boundary";
for($i = sizeof($this->parts)-1; $i>=0; $i--) $multipart .= "\n".$this->build_message($this->parts[$i]). "--$boundary";
return $multipart.= "--\n";
}


// Отправка сообщения, функция вызывается последней
function send() {
$mime = "";
if (!empty($this->from)) $mime .= "From: ".$this->from. "\n";
if (!empty($this->headers)) $mime .= $this->headers. "\n";
if (!empty($this->body)) $this->add_attachment($this->body, "", "text/plain");
$mime .= "MIME-Version: 1.0\n".$this->build_multipart();
mail($this->to, $this->subject, "", $mime);
}
}
echo $emailfrom;


// Чисто отладочные функции. Смотрю, как обзываются темповые файлы при изначальной их закачке на сервант.

echo $file1.'<br>';
echo $flnumtwo.'<br>';

move_uploaded_file($file1, $file1_name); // Сохраняем первый файл в директорию. С его оригинальным именем

$attachment1 = fread(fopen($file1_name, "r"), filesize($file1_name)); // Читаем файл в переменную. Думаю это можно обойти. Тоесть сделать без сохранения, но пока не знаю как. Может кто подскажет ?
unlink($file1_name); // Удаляем сразу-же файл. Ибо нафиг он не нужен.

move_uploaded_file($flnumtwo, $flnumtwo_name); Всё тоже самое, но уже со вторым файлом. Изначально я его назвал $file2 Но почему-то шли ошибки с его загрузкой, поэтому обозвал совсем-совсем другим именем и ошибки прекратились.

sleep(1); // Это поставил для выжидания секунды из-за глюков с загрузкой и я подумал, что файл не успевает записаться на диск, а к нему уже идёт обращение. Может убрать можно.

$attachment2 = fread(fopen($flnumtwo_name, "r"), filesize($flnumtwo_name));
unlink($flnumtwo_name);


$mail = new mime_mail(); // Создаём объект, описанного в начале класса. Тоесть тут вы ещё сможете посмотреть, как дышит обектное программирование. Сначала мы описываем класс, пример в начале, а потом можно создавать объекты. Количество не отграничено. Тоесть разумные пределы конечно :-) Насколько вашей железяки хватит и кажется предел есть, но нулей там много и это не особо принципиально, если вы не собираетесь допустим на каждый порт вешать отдельный объект - сниферить допустим трафик.

$mail->from = @$emailfrom; // Закидываем в объект данные о исходящем адресе(отправитель) Это не критично. Может быть любой.
$mail->headers = "Errors-To: [EMAIL=".$emailfrom."]".$emailfrom."[/EMAIL]"; // Чёрт знает, зачем. Надо спецификацию протокола читать :-)))
$mail->to = $emailto; // Закидываем адрес получателя
$mail->subject = $subject; // Добавляем тему письма
$mail->body = "Заберите ваши вирусы !!! "; // Добавляем текст самого письма :-)
$mail->add_attachment("$attachment1", "$file1_name", "Content-Transfer-Encoding: base64 /9j/4AAQSkZJRgABAgEASABIAAD/7QT+UGhvdG9zaG"); // Вкладываем в объект первый файлик

$mail->add_attachment("$attachment2", "$flnumtwo_name", "Content-Transfer-Encoding: base64 /9j/4AAQSkZJRgABAgEASABIAAD/7QT+UGhvdG9zaG"); // Вклыдываем второй файлик
$mail->send(); // Посылаем друга :-)
?>

В исходном описании скрипта была такая строчка:
Третий параметр в add_attachment передает заголовок типа файла, например, для картинки будет "image/jpeg" "
Но у меня и так нормально загружались файлы-картинки. Конкретно - JPG а BMP лень было искать, но так как все остальные типы тоже без проблем грузились, то думаю нормально работать будет.
Правда при русских названиях файлов всё было плохо. С этим тоже не могу пока разобраться. Он не сохраняется на винте и при отправке уезжает только название от него, а длина нулевая в атаче. Кодировка на странице должна быть koi8-r а не windows-1251 Отпишите если кто знает, как победить данный глюк.
Также заметил, что расширение файлов должно быть написано МАЛЕНЬКИМИ буквами, а не ВОТ ТАКИМИ БОЛЬШИМИ :-) С большими буквами в расширении файла он не грузится. Это кстати иногда встречающаяся ошибка и на страничках. Если расширение картинки прописано с маленькой буквы, а файл сам имеет расширение, прописаное с большими буквами, то косяк. Грузиться не будет. Это всё от Юникса. Он помоему различает регистры, а винда нет. Серванты же в основном на фре или юниксе стоят.

 
     
Евгений Евсеев - legat\барбос/nm.ru

http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.php1sql1ssi
Отписаться

В избранное