Главна цел на публикацията е изпращане на писмо с прикачен файл в PHP. Как става технически, за което нещата са сведени до възможния минимум, без капча, без проверки на страна на сървъра за коректност на подадените данни, без валидация на e-mail адрес, без лимит на броя символи и т.н.
Кое как беше - на помощ следните теми:
Форма за изпращане на електронно писмо с прикачен файл
Формата за изпращане на електронно писмо с прикачен файл в PHP изглежда така.
Нейната стилизация не е обект на публикацията. В HTML-частта нещата стоят така:
<form action="mail.php" method="post" enctype="multipart/form-data"> До <input type="text" name="email"> Относно <input type="text" name="subject"> Коментар <textarea name="description" cols="24" rows="10"></textarea> Прикачи <input type="file" name="attachment"> <input type="submit" name="submit" value="Go"> <input type="reset" value="Reset"> </form>
Две съставки са принципни за подобна дейност:
- enctype="multipart/form-data"
- input type="file"
multipart/form-data указва, че данните не се кодират. Това значение се използва при изпращане на файл, постъпил от поле file.
PHP процесор за обработка на формата
Първоначално следва да узнаем конкретни значения на директивите в php.ini. Извадката долу показва, че ползвам по подразбиране.
;;;;;;;;;;;;;;;;; ; Data Handling ; ;;;;;;;;;;;;;;;;; ; Maximum size of POST data that PHP will accept. ; Its value may be 0 to disable the limit. It is ignored if POST data reading ; is disabled through enable_post_data_reading. ; http://php.net/post-max-size post_max_size = 8M ;;;;;;;;;;;;;;;; ; File Uploads ; ;;;;;;;;;;;;;;;; ; Whether to allow HTTP file uploads. ; http://php.net/file-uploads file_uploads = On ; Temporary directory for HTTP uploaded files (will use system default if not ; specified). ; http://php.net/upload-tmp-dir ;upload_tmp_dir = ; Maximum allowed size for uploaded files. ; http://php.net/upload-max-filesize upload_max_filesize = 2M ; Maximum number of files that can be uploaded via a single request max_file_uploads = 20
Качването разрешено. До 20 файла едновременно с обем не повече от 2MB за брой, а общия обем на POST-данните не може да надхвърля 8MB.
Постъпилите данни от формата ще обработва mail.php. Съответно неговото съдържание:
<?php /** * PHP mailer with attachment * @author Profruit * @link http://profruit.blogspot.com * @copyright 2014 profruit.blogspot * @license GNU General Public License */ // проверка на формата if($_POST['submit'] !='Go'){ header("Location: index.html"); exit; } // получаване на масив $_POST $to = trim($_POST['email']); //до кого $sub = trim($_POST['subject']); //заглавие // тема на писмото $msg = trim($_POST['description']); $msg = wordwrap($msg,70); // от кого $from = "Profruit.blog <nobody@domain.com>"; // сепаратор на писмото $separator = md5(time()); // заглавки на писмото $headers = "From: {$from}\n"; $headers .= "MIME-Version: 1.0\n"; $headers .= "Content-Type: multipart/mixed;\n"; $headers .= " boundary=\"{$separator}\""; // тяло на писмото $message = "--{$separator}\n"; $message .= "Content-Type: text/plain; charset=\"utf-8\"\n"; $message .= "Content-Transfer-Encoding: 7bit\n\n"; $message .= $msg . "\n\n"; // прикачен файл на писмото if ($_FILES['attachment']['error'] == 0) { // получаване на масив $_FILES $tmpName = $_FILES['attachment']['tmp_name']; $fileType = $_FILES['attachment']['type']; $fileName = $_FILES['attachment']['name']; // прочит на прикачения файл $file = fopen($tmpName,'rb'); $data = fread($file,filesize($tmpName)); fclose($file); // кодиране на прикачения файл $data = chunk_split(base64_encode($data)); // добавяне на файла към писмото $message .= "--{$separator}\n"; $message .= "Content-Type: {$fileType};\n"; $message .= " name=\"{$fileName}\"\n"; $message .= "Content-Transfer-Encoding: base64\n\n"; $message .= $data . "\n\n"; $message .= "--{$separator}--\n"; } // изпращане на писмото if(mail($to, $sub, $message, $headers)){ echo "Писмото бе изпратено успешно до: $to"; } else{ echo "Възникна техническа грешка!"; } ?>
Пробег по редовете в помощ на коментарите на сценария.
В началото проверяваме натиснат ли е бутон Go, в противен случай обратно към индекса. Глобален масив POST "разпределяме по рафтовете".
В 29-ти ред генерираме сепаратор (boundary). Това е и същността за изпращане на писмо с прикачен файл. По сепаратора пощенския клиент ще се ориентира кое е заглавието, откъде започва тялото и съответно коя част, да счита за прикачен файл.
Следва минимум от заглавки на писмото, като последна носи значението на сепаратора. И пак с него маркираме старта на тялото (коментара на писмото). Ако има успешно прикачен файл, то след ред 44-ти скриптът се заема с неговата обработка и прилепване.
Файлът се качва в временен каталог. Според php.ini в Ubuntu се ползва каталог /tmp по подразбиране.
<?php echo sys_get_temp_dir(); // $temp_file = tempnam(sys_get_temp_dir(), $_FILES['uploadfile']['tmp_name']); // echo $temp_file;
Съответно глобален масив FILES също нареждаме акуратно по рафтовете. Узнаваме име и тип на файла, които ще посочим нататък. Временно качения файл в каталог /tmp четем в бинарен режим и полученото подаваме на функции base64_encode и chunk_split, а техния резултат в края на съобщението. Финален сепаратор и сбогом Гринго с функция mail. След нея каквото сабя покаже. Или радваме зомби-юзера, или му плюем малоумие - "опитай по-късно, че нещо се сецна по жицата".
Резултат в пощата на ABV.BG
От снимката горе става ясно, че формата и скрипта работят на ура. Става ясно кой е подател, неговия адрес за обратна връзка. Чете се адресанта, заглавието на писмото и коментара. Пощата на ABV.BG предлага преглед на прикачения файл или изтегляне на твърдия диск на абоната. И двете неща коректно работят.
По-голям интерес представлява детайлите на писмото, приложени в спойлера долу.
Нещата се повтарят в технически детайли. Става ясно, че писмото е изпратено/получено от www-data. Това е потребителското име на Apache 2.2 в Ubuntu. В качеството на трансферен пощенски агент се издава Exim 4.76. Сценарий mail.php е притежание на 1000, а това е ID на създателя на mail.php в Ubuntu. Става ясно как се нарича машината на собственика - prodesktop. Чете се неговото IP и име на доставчик. С думи прости - вие сте легален!
Резултат в пощата на GMail
Просто профит!
Всичко поднесено на длан. Прикачения файл е представен под формата на пиктограма. Детайлите на писмото, приложени в спойлера долу, показват на порции как е пристигнало писмото и се вижда отчетливо ролята на сепаратора.
до нови срещи ^.^
0 Response to "Изпращане на писмо с прикачен файл в PHP"
Публикуване на коментар