Если перед вами стоит задача сделать отправку письма с возможностью прикрепить несколько файлов, то в этом нет ничего сложного и в данном примере мы разберем что к чему, и как это реализовать с помощью функции 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->clearDir($obj) : unlink($obj); } } } //После отправки удаляем файлы из нашей директории clearDir($_SERVER['DOCUMENT_ROOT']."/img/"); setcookie("info","Сообщение успешно отправлено",time()+3600); header('Location: /online'); exit(); } else { $info .= " Возникла ошибка при отправке, повторите позднее"; header('Location: /online'); exit(); }
Надеюсь общий смысл ясен и какие то недочеты ребята вы сами поправите. Главное смысл. Если есть комментарии пожалуйста отписывайтесь где что не так. Я не претендую на истину, сам в заголовках этих плаваю, так что если будут пояснения то я их только приветствую!
Где то ошибка:
Parse error: syntax error, unexpected ‘&’
function clearDir( $dir ) {
if ($objs = glob($dir.”/*”)) {
foreach($objs as $obj) {
is_dir($obj) ? $this->clearDir($obj) : unlink($obj);
}
}
}
У меня почему то удаляются файлы .
а функцию в этой конструкции не нужно вызывать отдельно ?
извиняюсь. НЕ удаляются . после отправки
А можно для тех кто на бронепоезде готовый файл формы выложить? для изучения методом тыка. Второй день читаю, но так и не понял как это встроить в свою форму…
Заморочена статья, автор прыгает туда/сюда. Неужели нельзя было финальный вариант выложить как и многие авторы?
$f = $value['num'];
$f = fopen($filename,”rb”);
не понял мудрости этих 2-х строк – 1 строка: в переменную записывается значение и тут же во второй строке снова записываем другое значение……