PHP mail – письмо с несколькими вложениями файлов, multiple attachments

PHP mail - письмо с несколькими вложениями файлов, multiple attachmentsЕсли перед вами стоит задача сделать отправку письма с возможностью прикрепить несколько файлов, то в этом нет ничего сложного и в данном примере мы разберем что к чему, и как это реализовать с помощью функции mail без всяких библиотек.

И так, для того чтобы запулить письмо с вложениями то нам нужно правильно прописать заголовки письма, и насколько я разобрался в теме то в этих же заголовках и передаются прикрепленные наши файлы. Давайте начнем с функции которая будет непосредственно отправлять письмо с файлами. Я ее честно нашел вот тут, за что ребятам большое спасибо.

function XMail( $from, $to, $subj, $text, $files)
{

$un = strtoupper(uniqid(time()));
$head = "From: $from\n";
$head .= "To: $to\n";
$head .= "Subject: $subj\n";
$head .= "X-Mailer: PHPMail Tool\n";
$head .= "Reply-To: $from\n";
$head .= "Mime-Version: 1.0\n";
$head .= "Content-Type:multipart/mixed;";
$head .= "boundary=\"----------".$un."\"\n\n";
$zag = "------------".$un."\nContent-Type:text/html;\n";
$zag .= "Content-Transfer-Encoding: 8bit\n\n$text\n\n";

foreach($files as $key=>$value) {
$filename = './img/'.$key;
$f = $value['num'];
$f = fopen($filename,"rb");

$zag .= "------------".$un."\n";
$zag .= "Content-Type: application/octet-stream;";
$zag .= "name=\"".basename($filename)."\"\n";
$zag .= "Content-Transfer-Encoding:base64\n";
$zag .= "Content-Disposition:attachment;";
$zag .= "filename=\"".basename($filename)."\"\n\n";
$zag .= chunk_split(base64_encode(fread($f,filesize($filename))))."\n";

}

if (!@mail("$to", "$subj", $zag, $head))
return 0;
else
return 1;
}

Здесь все вроде почти просто. Мы должны передать необходимые значения в виде, от кого, кому, тему письма, текст сообщения и путь к нашему файлу или файлам если их несколько. Внутри функции в цикле прогоняется массив с файлами и формируется путь до наших файлов, которым мы предварительно залили на сервер.

Теперь сама форма с текстом и прочими плюшками. Поля могут быть какими угодно, для нас главное поле input=file у которого должен стоять атрибут multiple позволяющий выделять несколько файлов, либо можно сделать несколько полей с input=file но главное чтобы у них было name одинаковое. И во всех случаях name должно быть со скобками в конце дающее понять скрипту, что у нас массив а не одиночный файл, например name=myfile[].

</pre>
<div><label for="myfile">Прикрепите файл</label>
<input type="file" multiple="multiple" name="myfile[]" />
<input type="submit" name="go" /></div>
<pre>

Напоминаю вам, что все получаемые данные должны вами проверяться.

Теперь следующая удобная функия подсмотренная мною не помню где, которая переделывает массив $_FILES в удобный для нас, а также происходит копирование файлов в указанную нами директорию, например img:

//переворачиваем массив что бы с ним было удобно работать
foreach($_FILES as $fields) {
foreach($fields['name'] as $index => $file_name) {
$files[$file_name] = array(
'type' => $fields['type'][$index],
'num' => $index,
'tmp_name' => $fields['tmp_name'][$index]);
}
}
//удаляем пустые элементы массива
foreach($files as $key=>$value) {
if ($key=='') {
unset($files[$key]);
}
}

//перекидываем в img файлы
foreach($files as $key=>$value) {
$temp_path = './img/'.$key;
move_uploaded_file($value['tmp_name'], $temp_path);
}

Осталось заполнить наши переменные для передачи:

Начнем с адреса куда отправить, пусть у нас их будет два, один для отладки свой, второй клиента:

$to= "<blabla@gmail.com>" . ", " ; //обратите внимание на запятую
$to .= "<blabla@mail.ru>";

Переменную From я почему то у себя обозвал как email:

$email = “webmaster@blabla.ru”;

Сообщение – $message – любой текст, либо просто статичный текст либо переданный текст через форму.

$message = $txt;

Иногда нужно сделать конвертацию текста, тогда можно сделать так:

$txt = iconv("utf-8", "windows-1251", $txt);

Теперь сами заголовки. У меня почему то именно mail.ru и только он все письма принимал в крякозябрах. Пришлось прогонять текст темы письма следующим образом:

$online_theme="Письмо с сайта blabla";
$online_theme = iconv("utf-8", "windows-1251", $online_theme);
$online_theme = '=?windows-1251?B?'.base64_encode($online_theme).'?=';
 $headers  = "MIME-Version: 1.0\r\n";
 $headers .="Subject: {$online_theme}\r\n";
 $headers .= "Content-type: text/html; charset=\"windows-1251\"\r\n";

Ну и отправляем. Если была отправка без файлов, то отправляем простейшей функцией без изысков:

if ($_FILES['myfile']['error'][0]=='4') {
	if(mail($to,$online_theme,$message,$headers) !== FALSE)
		{      //можно поставить куку что все прекрасно отправилось:
			setcookie("info","Сообщение успешно отправлено",time()+3600);
			//Перекидываем на страничку формы:
                        header('Location: /online');
	  		exit();
		} else {
			$info .= " Возникла ошибка при отправке, повторите позднее";
		}
}

Финальная отправка если были переданы файлы:

if(XMail($email,$to,$online_theme,$message,$files) !== FALSE)
{
function clearDir( $dir ) {
if ($objs = glob($dir."/*")) {
foreach($objs as $obj) {
is_dir($obj) ? $this-&gt;clearDir($obj) : unlink($obj);
}
}
}
//После отправки удаляем файлы из нашей директории
clearDir($_SERVER['DOCUMENT_ROOT']."/img/");
setcookie("info","Сообщение успешно отправлено",time()+3600);
header('Location: /online');
exit();
} else {
$info .= " Возникла ошибка при отправке, повторите позднее";
header('Location: /online');
exit();
}

Надеюсь общий смысл ясен и какие то недочеты ребята вы сами поправите. Главное смысл. Если есть комментарии пожалуйста отписывайтесь где что не так. Я не претендую на истину, сам в заголовках этих плаваю, так что если будут пояснения то я их только приветствую!

Есть 5 коммент.

  1. Иван пишет:

    Где то ошибка:
    Parse error: syntax error, unexpected ‘&’

    function clearDir( $dir ) {
    if ($objs = glob($dir.”/*”)) {
    foreach($objs as $obj) {
    is_dir($obj) ? $this->clearDir($obj) : unlink($obj);
    }
    }
    }

  2. Создатель сайтов пишет:

    У меня почему то удаляются файлы .
    а функцию в этой конструкции не нужно вызывать отдельно ?

  3. Создатель сайтов пишет:

    извиняюсь. НЕ удаляются . после отправки

  4. Влад пишет:

    А можно для тех кто на бронепоезде готовый файл формы выложить? для изучения методом тыка. Второй день читаю, но так и не понял как это встроить в свою форму…

  5. Xacatel пишет:

    Заморочена статья, автор прыгает туда/сюда. Неужели нельзя было финальный вариант выложить как и многие авторы?

Написать комментарий

XHTML: Вы можете использовать эти теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*

*