Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

web - tec / PHP 5 для начинающи

.pdf
Скачиваний:
72
Добавлен:
12.06.2015
Размер:
26.79 Mб
Скачать

592 Глава 15

id 1AjqVG-0005LN-00

for <info@servata.com>; Thu, 22 Jan 2004 17:52:58 -0800

Received: (qmail 30557 invoked by uid 99); 23 Jan 2004 01:23:04 -0000 To: info@servata.com

Date: Thu, 22 Jan 2004 16:23:43 -0800

From: Michael Robertson <mailer@mailer.lindows.com>

Subject: Michael's Minute: Disagree with Linus MIME-Version: 1.0 Content-Type: multipart/alternative;

boundary="—-=_LINDOWS_34a8357a5a341381f6a48042673dcb9c" Message-Id: <E1AjqVG-0005LN-00@mail1.servata.com>

Lindows.com Michael's MinuteFrom: Michael Robertson [mailer@mailer.lindows.com] Sent: Thursday, January 22, 2004 4:24 PM

To: info@servata.com

Subject: Michael's Minute: Disagree with Linus If this message is not displaying properly, click here to launch it in your browser.

Michael's Minute: Disagree with Linus

I've never personally met Linus Torvalds, the much heralded man behind Linux. ...

some computer manufacturers are now shipping computers preinstalled with

desktop Linux through major retailers, making it practical

for average or even new computer users to embrace Linux.

...

Отправка e-mail с помощью PHP

Прежде чем приступить к практическому рассмотрению отправки e+mail+сооб+ щений, необходимо проверить некоторые параметры как в Windows+, так и в Linux+инс+ талляции PHP.

В Windows должен быть доступ к SMTP+серверу ++++++ это может быть сервер ISP, если разработка ведется на персональной машине. Откройте файл php.ini и найдите раздел [mail function]. Задайте соответствующее значение для параметра SMTP; например:

SMTP = smtp.my.server.net

Затем задайте такое значение параметра sendmail_from, которое отражало бы ваш e+mail+адрес, например:

sendmail_from = davidm@doggiestouch.co.za

Linux+пользователям придется только установить параметр sendmail_path:

sendmail_path = smtp.my.server.net

Это все. Теперь можно использовать функцию mail() для отправки электрон+ ной почты.

Использование функции mail()

Функция mail() возвращает булево значение, т.е. можно использовать оператор if для проверки успешности ее выполнения. В качестве аргументов данная функция при+ нимает адрес получателя, тему сообщения, тело сообщения и любые дополнительные заголовки, которые желательно отправить. Для отправки писем подходит код, подоб+ ный приведенному ниже. В данном случае письмо отправляется по заданному адресу и имеет тему и тело, состоящее из трех строк, разделенных символами новой строки (\n):

If (mail("joeblow@example.com", "Тема", "Первая строка\nВторая строка\nТретья строка")) { //сообщить пользователю, что письмо отправлено

} else {

//сообщить пользователю об ошибке

}

PHP5 и электронная почта 593

Практика Отправка e-mail-сообщения

Вызванная в PHP+приложении функция mail() отправляет письма через стан+ дартный MTA+агент. Логично предположить, что функция требует, как минимум, ад+ реса получателя, тему сообщения и само сообщение (которое обычно называется те+ лом). Чтобы добавить адрес отправителя (From) или любую другую дополнительную информацию, при формировании e+mail можно включить дополнительные заголовки. Рассмотрим небольшой сценарий mail.php (не забудьте заменить e+mail+адрес в пе+ ременной $to ++++++ предположим, что письмо необходимо отправить самому себе):

<?php

$to = "edit@contechst.com"; $subject = "Ваше письмо отправлено"; $body = "Тестовое письмо";

if(mail($to,$subject,$body)){

echo "<b>PHP отправил Ваше e-mail-письмо<b>";

}

?>

Если сетевое соединение установлено и SMTP+сервер работает правильно, то в ок+ не браузера будет выведено подтверждающее сообщение. Следует, однако, отметить, что успешная отправка письма не означает, что это письмо будет принято получате+ лем. Существует множество причин, по которым почта не доходит до получателя ++++++

указанный в письме адрес получателя может не соответствовать адресу на прини+ мающем сервере, принимающий сервер может быть временно недоступен и т.д.

Как это работает

PHP+функция mail() позволяет пользователю отправлять e+mail+сообщения, ука+ зав несколько аргументов (таких как адрес получателя). Это булева функция, т.е. она возвращает TRUE при успешном завершении (почта была отправлена) и FALSE в про+ тивном случае. Аргументы можно указывать в виде текстовых строк или в виде пере+ менных, содержащих соответствующие данные.

Предположим, что письмо дошло до адресата. Результат показан на рис. 15.1. Рассмотрим каждый аргумент, принятый функцией mail().

Заголовок ‘‘To:’’ автоматически добавляется функцией, а данные для него считы+ ваются из первого аргумента. Эти данные можно жестко запрограммировать, принять как переменную, сгенерированную в результате отправки пользователем формы (этот случай иллюстрируется далее) либо получить их из записей в базе данных или иного источника информации. В этом поле можно указать несколько получателей, разделяя e+mail+адреса запятыми (без пробелов). Запятые должны находиться между кавычка+ ми, окружающими e+mail+адреса, иначе они будут интерпретированы функцией как следующий аргумент.

Тема e+mail+сообщения автоматически считывается из второго аргумента функции. Тему также можно жестко запрограммировать, принять как значение переменной, полученное в результате отправки формы, или вставить из любого источника данных. Конечно, было бы немного странно отправлять всем получателям разные темы (если вы не спамер), но это определенно возможно.

Тело сообщения состоит из текста, и в него можно добавить слова приветствия и подпись. Тело сообщения ++++++ просто текст, и любые начальные и конечные фраг+ менты или другие компоненты добавляются с помощью оператора конкатенации (.).

594 Глава 15

Рис. 15.1.

Дополнительные заголовки, такие как ‘‘Form:’’, можно добавлять как текстовые строки в качестве четвертого аргумента функции mail(). Каждый аргумент прини+ мает форму заголовка, начинающегося с соответствующего ключевого слова с после+ дующим двоеточием, например, From:. После ключевого слова следует строка, со+ держащая имя и e+mail+адрес (в угловых скобках) отправителя. Эта строка завершается символами возврата каретки и перевода строки. Следующий пример показывает, как формируется заголовок ‘‘From:’’:

"From: $sender_name <$from>\r\n"

Если добавляются другие заголовки, то они могут быть собраны в переменной $headers при условии, что каждый из них завершается символами перевода строки и возврата каретки.

Некоторые MTA в Unix могут работать только с символом новой строки (\n).

В простом приложении, которое разрабатывается далее в настоящей главе, ис+ пользуются e+mail+адреса, вставляемые по одному за раз, но в более сложных прило+ жениях (например, в диспетчерах рассылки новостей) для обработки множества e+mail+адресов могут использоваться циклы, такие как for или do while. Источника+ ми e+mail+адресов для приложения могут быть записи базы данных, .xml+файлы или даже простые текстовые файлы.

До сих пор в книге рассматривались только простые текстовые сообщения. А что если в e+mail+письмо необходимо добавить вложение или отправить вместо простого текста данные другого формата? Далее описаны способы, позволяющие решать эти проблемы.

PHP5 и электронная почта 595

Многоцелевые расширения почты в Internet (MIME)

Формат MIME расширяет e+mail за рамки простого текста, позволяя указывать тип содержимого и кодировку сообщения. Формат MIME определяется стандартом RFC 2045, который опубликован на странице www.faqs.org/rfcs/rfc2045.html.

Поля MIME-заголовков

Как базовый текстовый e+mail+протокол, MIME использует поля заголовков для опре+ деления содержимого и структуры e+mail+сообщений, содержащих нестандартное тексто+ вое наполнение, а также присоединяемые файлы. MIME+заголовки описываются ниже.

MIME Version (версия MIME): указывает на то, что сообщение в целом соответ+ ствует RFC, если используется версия 1.0.

Content+Type (тип содержимого): указывает на тип тела сообщения или вло+ женного файла. Отсутствие этого заголовка свидетельствует о том, что исполь+ зуется простой текстовый формат. Например, для отправки e+mail+сообщений в формате HTML (это очень популярно в наши дни) необходимо установить за+ головки версии MIME и типа содержимого подобным образом:

$headers .= "MIME-Version: 1.0 \n";

$headers .= "Content-type: text/html; charset=iso-8859-1 \n";

Content+Transfer+Encoding (транспортная кодировка содержимого): указывает кодировку данных, например, base64 для файла изображения.

Content+Id (идентификатор содержимого; необязательный заголовок с исклю+ чениями): уникально обозначает MIME+блоки в сообщении, позволяя одному телу идентифицировать другое.

Content+Description (необязательный заголовок): текстовое описание содер+ жимого.

Content+Disposition (расположение содержимого): рекомендует клиентскому при+ ложению способ интерпретации части сообщения, к которой применяются те+ кущие заголовки. Значением может быть attachment (вложение) или inline (непосредственно). Как и следует ожидать, часть сообщения присутствует либо в виде вложенного файла, либо отображается непосредственно. Непосредственное отображение удобно для HTML+писем, в которых используются изображения.

Многоэлементный MIME-формат

Формат MIME предусматривает отправку e+mail+сообщений с вложениями. Такие сообщения называются многоэлементными MIME*сообщениями (multipart MIME messages), потому что MIME+секция сообщения разделяется не несколько частей, каждая из ко+ торых имеет собственные MIME+заголовки. Общий тип содержимого (Content+Type) для таких сообщений ++++++ multipart/mixed, но в каждой подсекции может быть уста+ новлен ее собственный тип, например, text/html или другой.

Маркеры границ

Частью многоэлементного MIME+сообщения является конструкция маркера гра+ ниц. При создании сообщения устанавливается параметр (который называется грани* ца (boundary)), равный произвольно определенной текстовой строке. Это произволь+ ная строка, но она не должна встречаться в теле сообщения (т.е. не должна быть

596 Глава 15

распространенным словом). Для создания маркеров границ можно задействовать функцию md5(), используя при этом значение текущего времени и какой+либо произ+ вольный текст. В этом случае крайне маловероятно, что маркер границы встретится в составе тела сообщения.

Рассмотрим секции многоэлементного MIME+сообщения, которое представлено ниже. Следует отметить, как определяется, а затем используется граница для разделе+ ния разных частей целого сообщения.

//начало заголовка

MIME-Version: 1.0

Content-Type: multipart/mixed; boundary="0000_PHP5_0000";

Content-Transfer-Encoding: 7bit

Эта часть e-mail не должна быть видимой для того, кто читает письмо, при условии, что он использует MIME-совместимый e-mail-клиент.

--0000_PHP5_0000

//текстовый заголовок

Content-Type: text/plain; charset="iso-8859-1"

Content-Transfer-Encoding: 7bit

Это тело сообщения и оно должно быть простым читабельным текстом.

--0000_PHP5_0000

//заголовок для вложенного изображения

Content-Type: image/jpeg; name="myimage.jpg";

Content-Transfer-Encoding: base64

Content-Disposition: attachment

<данные файла myimage.jpg в кодировке base64>

--0000_PHP5_0000

//заголовок непосредственно вставленного изображения

Content-Type: image/jpeg; name="myimage.jpg";

Content-Transfer-Encoding: base64

Content-Disposition: inline

<данные файла myimage.jpg в кодировке base64>

--0000_PHP5_0000

HTML-письма

Хотя обычные e+mail+сообщения состоят из простого текста, можно так установить MIME+заголовки, чтобы тело сообщения передавалось в HTML+формате. В приложе+ нии, разработка которого рассматривается ниже, используется переключатель, для того чтобы пользователь мог выбрать формат письма ++++++ простой текст или HTML. Если пользователь выбрал HTML, то приложение создает MIME+заголовки, в которых определяется тип содержимого (Content+Type) ++++++ text\html.

В дополнение к правильной установке заголовков для формата HTML, в приложе+ нии используется весьма удобный инструмент, позволяющий пользователю создавать HTML+код изображениями и текстом. Речь идет о JavaScript+сценарии htmlArea, соз+

PHP5 и электронная почта 597

данным и бесплатно распространяемым компанией Interactivetools.com, Inc. Неболь+ шой фрагмент кода для вставки редактора htmlArea показан в коде Web+страницы приложения, хотя его исходный код не приводится. Весь код и изображения, состав+ ляющие редактор, можно загрузить с сайта www.interactivetools.com. Он не свя+ зан с какими+либо почтовыми функциями PHP, но очень удобен, так как позволяет ви+ зуально создать тело сообщения для HTML+письма.

Библиотеки почтовых функций в PEAR

Репозиторий PEAR содержит несколько классов, которые можно использовать для работы с электронной почтой. Чтобы заставить их работать в PHP+сценариях, пона+ добится установить соответствующие PEAR+библиотеки (более подробная информа+ ция о PEAR приведена в главе 14).

После установки можно поэкспериментировать с новыми экземплярами почтовых PEAR+объектов. В состав почтовых классов PEAR входят следующие пакеты:

Mail: отправляет e+mail+сообщения с помощью встроенной в PHP функции mail();

Mail_IMAP: предоставляет функции библиотеки c+client для Web+почты;

Mail_Mbox: PHP+класс для разбора и использования Unix MBOX;

Mail_Mime: предоставляет классы для создания и декодирования MIME+ сообщений;

Mail_Queue: позволяет накапливать почту в очередях, а затем отправлять ее в фоновом режиме.

Создание простого PHP-приложения для работы с e-mail

Разрабатываемое здесь приложение способно создавать и отправлять e+mail+ сообщения, используя MIME+формат и PHP+функцию mail(); здесь предполагается, что установлена программа Sendmail. Чтобы приложение могло отправлять письма с несколькими вложенными файлами, эти файлы должны находиться на локальном сервере. (В главе 7 рассматривалось создание простого приложения, позволяющего загружать файлы на сервер. Будем считать, что блок загрузки файлов уже выполнил свои функции и что необходимые файлы были помещены в каталог atts.)

Приложение считывает файлы и предоставляет пользователю возможность вы+ брать (из списка) один или несколько файлов для отправки их в письме. При отправке HTML+писем пользователь может указать имена файлов, присутствующих в каталоге atts, и отправить их вместе с письмом для непосредственного отображения в сообщении.

Когда пользователь открывает приложение в браузере, появляется HTML+страница. JavaScript+сценарий добавляется в дескрипторе <head> этой страницы и создает визу+ альный HTML+редактор (редактируемую текстовую область). После тега </head> от+ крывается дескриптор <body> и таблица, заключающая в себе всю форму. Позднее дру+ гой JavaScript+блок в элементе формы фактически вызывает первый JavaScript+сценарий для создания текстовой области; следует отметить, что это происходит, если использу+ ется браузер Internet Explorer версии 5.5 или выше. Итак, запустите HTML+редактор и начинайте вводить следующий код. По мере рассмотрения функций различных час+ тей создаваемого приложения здесь будут поясняться новые фрагменты кода.

598 Глава 15

<html>

<head>

<title>Почтовые функции PHP</title>

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <script language="Javascript1.2"><!-- // Загрузить htmlarea

_editor_url = "http://www.bigtip.com/php5/Chapter15/htmlarea/"; // URL к файлам htmlarea

var win_ie_ver = parseFloat(navigator.appVersion.split("MSIE")[1]); if (navigator.userAgent.indexOf('Mac') >= 0) { win_ie_ver = 0; }

if (navigator.userAgent.indexOf('Windows CE')>=

0)

{ win_ie_ver = 0; }

if (navigator.userAgent.indexOf('Opera')

>=

0)

{ win_ie_ver = 0; }

if (win_ie_ver >= 5.5) {

 

 

 

document.write('<scr' + 'ipt src="' +_editor_url+ 'editor.js"'); document.write(' language="Javascript1.2"></scr' + 'ipt>'); } else {

document.write('<scr'+'ipt>function editor_generate(){ return false; }</scr'+'ipt>'); }

// --></script> </head>

<body bgcolor="#FFFFFF">

<table width="100%" border="0" cellpadding="10"> <tr>

<td>

<h2>Использование PHP для отправки e-mail</h2>

В этом месте HTML+кода логично разместить форму. Так как форма должна ото+ бражать перечень файлов в каталоге atts, готовых к отправке в виде вложений, не+ обходимо проинициализировать переменную $default_directory так, чтобы она содержала имя этого каталога:

<?php

//Каталог для присоединяемых файлов $default_dir = "./atts";

Если пользователь уже видел форму, заполнил и отправил ее, то запускать главный PHP+код нет необходимости. Поэтому в условии оператора if используется переменная $_POST['posted'] для проверки того, была ли отправлена форма. Если форма была отправлена, то PHP+код может начинать формирование e+mail+сообщения для отправки.

Если форма не была отправлена, то условие оператора if ложно (переменная $_POST['posted'] не установлена), весь PHP+код обработки данных формы пропус+ кается и отображается HTML+форма. Очевидно что когда пользователь впервые от+ крывает страницу или когда обновляет ее, не нажимая кнопку Отправить, PHP+код обработки данных формы не выполняется ++++++ вместо этого выводится сама форма.

Следующий фрагмент кода проверяет, была ли отправлена форма, и если да, то за+ писывает имя отправителя в переменную:

if (!empty($_POST)) {

$sender_name = $_POST['first_name'] . " " . $_POST['last_name'];

Далее с помощью значения, сформированного переключателем html_or_text, выясняется тип отправляемого сообщения (HTML+сообщение: письмо с вложением или письмо в стандартном, простом текстовом формате):

if ($_POST['html_or_text'] == "html") {

Если значение переключателя равно html, то необходимо определить наличие присоединяемых файлов, проверив количество элементов в массиве $attachments:

if (count($_POST['attachments']) > 0) {

PHP5 и электронная почта 599

Если количество элементов больше нуля (есть файлы для отправки), то инициали+ зируем переменную счетчика ($cnt) со значением 0 и создаем значение маркера гра+ ницы для разделения MIME+заголовков:

$cnt = 0;

$boundary = "0000_PHP5_0000";

Затем сценарий в цикле проходит по всем присоединяемым файлам, открывает каж+ дый из них, извлекает его содержимое и создает соответствующий MIME+заголовок, разделяя одновременно с этим содержимое файла на блоки, а затем закрывает файл:

for ($i = 0; $i < count($_POST['attachments']); $i++) {

$fp = fopen($default_dir . "\\" . $_POST['attachments'][$i],"rb");

$file_name = basename($_POST['attachments'][$i]); $content[$cnt] = fread($fp,filesize($default_dir . "/" .

$_POST['attachments'][$i])); $files_attached = ""; $files_attached.="--$boundary\n"

."Content-Type: image/jpeg; name=\"$file_name\"\n"

."Content-Transfer-Encoding: base64\n"

."Content-Disposition: inline; filename=\"$file_name\"\n\n"

.chunk_split(base64_encode($content[$cnt]))."\n"; $cnt++;

fclose($fp);

}

После того как вложения сформированы, создаются заголовки From:, CC:, BCC: и Reply+To:; строка приветствия, тело сообщения и подпись, а затем главный MIME+ заголовок (хотя HTML+сообщения могут также содержать вложения, здесь эта воз+ можность не рассматривается; предположим, что основное сообщение имеет простой текстовый формат):

$from_header = "From: $sender_name <$_POST[from]>\nCC: $_POST[cc] \nBCC: $_POST[bcc]\nReply-To: $_POST[from]\n";

$salutation = $_POST['salutation'] . "\n\n";

$body = $salutation . $_POST['body'] . "\n\n" . $_POST['regards'];

//Создаем главный MIME-заголовок, добавляем тело сообщения и

//присоединяемые файлы

$files_attached .= "--".$boundary."\n"; $add_header = "";

$add_header .="MIME-Version: 1.0\n" ."Content-Type: multipart/mixed; boundary=\"$boundary\"; Message-ID: <".md5($_POST['from'])."@example.com>";

$mail_content="--".$boundary."\n"

."Content-Type: text/plain; charset=\"windows-1251\"\n"

."Content-Transfer-Encoding: 8bit\n\n"

.$body."\n\n".$files_attached;

$body = $mail_content;

Следует отметить, что переменной $body присваивается значение переменной $mail_content (в которой содержится тело сообщения и содержимое присоединяе+ мых файлов). Таким образом, впоследствии можно просто передать значение пере+ менной $body функции mail().

Если e+mail+сообщение форматируется как HTML, то перед отправкой сообщения используется следующий код для создания нескольких заголовков:

} else {

$salutation = $_POST['salutation'];

600 Глава 15

$salutation = $salutation . "<br><br>";

$body = $salutation . stripslashes($_POST['body']) . "<br><br>" . $_POST['regards'];

// Формируем HTML-заголовки

$from_header = "From: $sender_name <$_POST[from]>\nCC: $_POST[cc]\nBCC: $_POST[bcc]\nReply-To: $_POST[from]\n";

$add_header = "MIME-Version: 1.0\n";

$add_header .= "Content-type: text/html; charset=windows-1251\n";

}

Для простых текстовых e+mail+сообщений также формируются заголовки:

}else {

//для простых текстовых сообщений без вложений

$from_header = "From: $sender_name <$_POST[from]> \nCC: $_POST[cc]\nBCC: $_POST[bcc]\nReply-To: $_POST[from]\n";

$salutation = $_POST['salutation']; $salutation = $salutation . "\n\n"; $body = $_POST['body'];

$body = $salutation . $body . "\n\n" . $_POST['regards'];

}

Затем адреса получателей (To:) записываются в одну переменную $to:

$to = "$_POST[to]";

do{

next($_POST);

}while (key($_POST) !== 'to'); for ($i = 1; $i <=7; $i++) {

$next = next($_POST); if(!empty($next)){

$to = $to . ", " . $next;

}

}

После чего выполняется минимальная проверка e+mail+адресов и почта отправля+ ется. Если почта не отправлена или в e+mail+адресе есть ошибка, то выводится соот+ ветствующее сообщение:

if (strpos($_POST['to'],"@") >= 0) {

// Отправляем почту echo "<BR>To: $to<P>";

echo "Subject: $_POST[subject]<P>"; echo "Body: $body<P>";

echo "$from_header<P>"; echo "$add_header<P>"; if(!isset($add_header)){

if (mail($to, $_POST['subject'], $body)){ echo "<h3>Ваше письмо отправлено</h3>";

} else {

echo "Возникла ошибка и письмо не было отправлено";

}

}else if (mail($to, $_POST['subject'], $body, "$from_header". "$add_header")) {

echo "<h3>Ваше письмо отправлено</h3>";

} else {

echo "Возникла ошибка и письмо не было отправлено";

}

} else {

echo "Обнаружен неправильный e-mail-адрес";

}

PHP5 и электронная почта 601

Если пользователь не отправлял форму, то следует просто отобразить ее и дать пользователю возможность ввести свой e+mail+адрес и другие данные:

} else { ?>

<form method="POST" action="php_mail.php"> <input type="hidden" name="posted" value="true">

<table width="100%" border="1"> <tr>

<td width="16%" valign="top"><font face="Arial, Helvetica, sans-serif" size="-1"><b>Ваше имя:</b></font></td> <td width="84%"><font size="-1" face="Arial, Helvetica,

sans-serif"><b>Имя</b></font>

<input type="text" name="first_name">

<b><font size="-1" face="Arial, Helvetica, sansserif">Фамилия</font></b>

<input type="text" name="last_name"> </td>

</tr>

<tr>

<td width="16%" valign="top"><b><font face="Arial, Helvetica, sans-serif" size="-1">От:</font></b></td> <td width="84%">

<input type="text" name="from"> </td>

</tr>

<tr>

<td width="16%" valign="top"><b><font face="Arial, Helvetica, sans-serif" size="-1">Кому:</font></b></td> <td width="84%">

<input type="text" name="to"> <input type="text" name="to01"> <input type="text" name="to02"> <input type="text" name="to03"> <input type="text" name="to04"> <input type="text" name="to05"> <input type="text" name="to06"> <input type="text" name="to07">

</td>

</tr>

<tr>

<td width="16%" valign="top"><b><font face="Arial, Helvetica, sans-serif" size="-1">Копия (CC):</font></b></td> <td width="84%">

<input type="text" name="cc"> </td>

</tr>

<tr>

<td width="16%" valign="top"><b><font face="Arial,

Helvetica, sans-serif" size="-1">Скрытая копия (BCC):</font></b></td> <td width="84%">

<input type="text" name="bcc"> </td>

</tr>

<tr>

<td width="16%" valign="top"><b><font face="Arial, Helvetica, sans-serif" size="-1">Тема:</font></b></td> <td width="84%">

<input type="text" name="subject"> </td>

</tr>

<tr>

<td width="16%" valign="top"><b><font face="Arial, Helvetica, sans-serif" size="-1">Вложения:<br>

Соседние файлы в папке web - tec