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

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

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

582 Глава 14

static $strMyMP3Directory = "/home/ed/mp3"; # Укажите реальный каталог с MP3-файлами $objDir = dir($strMyMP3Directory);

$intNumFiles = 0; $arMP3Files = Array();

while (false !== ($strEntry = $objDir->read())) { if (eregi("\.mp3$", $strEntry)) {

$arMP3Files[] = $strMyMP3Directory . "/" . $strEntry;

};

};

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

Получение имени исполнителя из каждого файла ++++++ первая цель использования класса MP3_ID:

$objMP3ID = new MP3_Id(); $arArtists = Array(); $arTestArtists = Array();

for ($i=0; $i<=sizeof($arMP3Files)-1; $i++) { $strPath = $arMP3Files[$i];

$intResult = $objMP3ID->read ($strPath);

$strArtist = $objMP3ID->getTag ("artists", "Unknown Artist"); $strTestArtist = strtoupper(preg_replace("/[^A-Za-z0-9]/", "", $strArtist));

if (in_array($strTestArtist, $arTestArtists) == false) { array_push($arArtists, $strArtist); array_push($arTestArtists, $strTestArtist);

};

};

Следует отметить, что создается два массива ++++++ $arArtists, содержащий имена исполнителей, и $arTestArtists с измененной версией каждого имени, где все бук+ вы переведены в верхний регистр и удалены все не алфавитно+цифровые символы (включая пробелы). Это сделано по одной причине: необходимо убедиться, что каж+ дый исполнитель появляется в списке только один раз. Удаление пробелов и знаков препинания, а также перевод всех символов в верхний регистр позволяет с большой долей уверенности сравнить имя исполнителя, извлеченное из IDv3+тега, с тем име+ нем, которое уже встречалось в течение времени жизни цикла.

В качестве примера рассмотрим вымышленного исполнителя ‘‘Extreme Metal Grind+ ing’’. Предположим, что в коллекции имеется три композиции этого исполнителя, соз+ данных в разное время тремя различными программами. Имя исполнителя в IDv3+теге вполне может быть представлено тремя незначительно отличающимися способами, на+ пример, ‘‘Extreme Metal Grinding’’, ‘‘EXTREME ‘Metal’ Grinding’’ и ‘‘Extreme Metalgrind+ ing’’. Использованное в операторе $strTestArtist = strtoupper (preg_replace ("/[^A-Za-z0-9]/", "", $strArtist)) регулярное выражение и преобразова+ ние к верхнему регистру для каждого из этих тегов позволяет всегда получать один и тот же результат: EXTREMEMETALGRINDING. Вероятно, на экране такое имя будет выглядеть некрасиво, но оно хорошо подходит для сравнения и создания учетной за+ писи для этой группы исполнителей.

Итак, в цикле просматривается каждый MP3+файл и из него извлекается имя ис+ полнителя, к которому применяется регулярное выражение. Затем нужно проверить, присутствует ли измененное имя исполнителя в тестовом массиве. Если это не так, то имя исполнителя записывается в оба массива ++++++ в тестовый массив (сюда записывается

PEAR 583

измененное имя) и в реальный массив имен исполнителей (записываются исходные име+ на). Если имя записано в тестовом массиве, то нет необходимости добавлять его снова.

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

Имена всех исполнителей в только что созданном массиве обрабатываются с по+ мощью следующего цикла:

$arTracks = Array(); $arAlreadyAccountedForSongIndices = Array(); for ($i=0; $i<=sizeof($arArtists)-1; $i++) {

$strArtistName = $arArtists[$i]; $strTestArtistName = $arTestArtists[$i]; $arTracks[$strArtistName] = Array();

for ($j=0; $j<=sizeof($arMP3Files)-1; $j++) {

if (in_array($j, $arAlreadyAccountedForSongIndices) == false) { $strPath = $arMP3Files[$j];

$intResult = $objMP3ID->read ($strPath);

$strThisArtist = $objMP3ID->getTag ("artists", "Unknown Artist"); $strThisTestArtist = strtoupper(preg_replace("/[^A-Za-z0-9]/", "",

$strThisArtist));

if ($strThisTestArtist == $strTestArtistName) { array_push($arAlreadyAccountedForSongIndices, $j); $arSongHash["TITLE"] = $objMP3ID->getTag ("name", "Unknown Title"); $strSongFilename = str_replace("$strMyMP3Directory" . "/", "",

$arMP3Files[$j]);

$arSongHash["LINK"] = "radiorequest.php?requestfile=" . urlencode($strSongFilename);

array_push($arTracks[$strArtistName], $arSongHash);

};

};

};

};

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

Затем для каждого ключа просматривается весь список MP3+файлов и проверяет+ ся, принадлежит ли каждая композиция данному исполнителю. Имя исполнителя, хранящееся под соответствующим индексом в тестовом массиве, сверяется с именем исполнителя в MP3+файле, которое предварительно обрабатывается регулярным вы+ ражением. Это, как уже было сказано, позволяет игнорировать различия в количестве пробелов, знаков препинания и регистре символов.

Чтобы определить, какие песни принадлежат тому или иному исполнителю, всю коллекцию приходится просматривать в цикле. Вследствие этого рассматриваемый сценарий может потреблять значительные ресурсы и работать медленно. Поэтому для повышения производительности необходимо связать каждый индекс массива MP3+ файлов ($arMP3Files) с исполнителем только один раз ++++++ композиция, для которой

584 Глава 14

создан MP3+файл, может быть написана только одним исполнителем, по крайней мере, ес+ ли рассматривать IDv3+теги. Выполняется проверка по искомому индексу, и если этот ин+ декс уже связан с исполнителем, то нет смысла тратить на него время. Как только принад+ лежность заданного MP3+файла определена (индекс j в исходном массиве $arMP3Files), этот индекс добавляется в другой массив $arAlreadyAccountedForSongIndices. В результате можно не проверять этот MP3+файл при последующих итерациях, если его принадлежность данному исполнителю уже установлена. Это значительно по+ вышает производительность, поскольку ограничивается количество необходимых операций чтения IDv3+тегов.

Если имя исполнителя проверяемой записи совпадает с именем исполнителя, чье авторство проверяется в текущий момент, то в массив с индексом текущего исполни+ теля добавляется соответствующий массив, представляющий эту запись. Добавляемый массив содержит название песни и ссылку (содержащую имя файла без пути) на стра+ ницу radiorequest.php. Идея заключается в том, что когда пользователь щелкает по этой ссылке, он фактически подтверждает, что хочет прослушать эту песню. Что+ бы гарантировать, что создаваемый URL будет корректно обрабатываться Web+ браузером, используется функция urlencode.

Наконец, для сортировки массива по ключам в алфавитном порядке используется функция ksort. Почти так же как и функция arsort, которая использовалась в пре+ дыдущем MP3_ID+приложении, ksort сохраняет в ассоциативном массиве внутрен+ нюю связь между каждым ключом и его значением:

ksort($arTracks);

Используя созданную структуру данных, можно выводить XML+код.

Так как генерируемый XML+код крайне прост, преимущества встроенной PHP5+ библиотеки libxml для поддержки XML не используются. Вместо этого XML+вывод создается так же, как если бы это был HTML+код. Однако вполне можно переписать соответствующую подпрограмму, так чтобы она использовала libxml2 (см. главу 8).

Весьма простая рекурсия позволяет обработать структуру данных и отправить вы+ вод непосредственно в браузер. Обоснование для использования в предыдущем блоке кода внешне громоздкой структуры данных теперь должно быть очевидным ++++++ можно конвертировать структуры данных в XML, используя всего несколько строк кода. В результате программист немного усложняет себе работу, но вместе с тем упрощает генерирование XML+кода. Это пригодится, если впоследствии придется по какой+ либо причине подправить XML+код ++++++ это можно будет легко сделать, не затрагивая многочисленных строк сложной логики.

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

<treemenu>

<? foreach ($arTracks as $artist_name => $arHash) { ?> <node text="<?=$artist_name?>" icon="folder.gif">

<? for ($i=0; $i<=sizeof($arHash)-1; $i++) { ?>

<node text="<?=htmlentities($arHash[$i]["TITLE"])?>" icon="document.gif" link="<?=htmlentities($arHash[$i]["LINK"])?>" />

<? }; ?> </node>

<? }; ?> </treemenu>

При генерации обоих значений (названия записи и ссылки) используется функция htmlentities, гарантирующая, что вывод будет полностью соответствовать XML+ стандарту. Это может в буквальном смысле исказить URL, но синтаксический анали+ затор компонента HTMLTree_Menu исправит это неудобство.

PEAR 585

Теперь можно открыть страницу radiogeneratexml.php в Web+браузере. Чтобы заставить Internet Explorer отображать страницу как XML (что сделает ее более удо+ бочитаемой и позволит разворачивать и сворачивать отдельные узлы), можно ис+ пользовать следующий трюк с URL:

http://your_server_name/radiogeneratexml.php/.xml

Web+сервер игнорирует лишние символы /.xml в конце, но Internet Explorer ‘‘пола+ гает’’, что пользователь определенно запрашивает XML+страницу и поэтому отобра+ жает ее как следует. (Непонятно, почему этот браузер не учитывает MIME+заголовок, для создания которого пришлось приложить определенные усилия в начале сценария.)

Чтобы полностью убедиться, что все работает, можно скопировать XML+код, вста+ вить его в файл treemenutest.xml, а затем открыть страницу treemenutest.php снова. Чтобы сделать это, просто откройте в браузере предыдущий URL. В окне дол+ жен появиться XML+код, в котором можно найти MP3+файлы. Если все выглядит нор+ мально, то можно считать, что большая часть работы сделана.

Как это работает: сценарий radiorequest.php

Файл radiorequest.php до сих пор был самым простым из двух файлов. Работа этого сценария будет понятна, если вы знаете, как работает radiogeneratexml.php.

Сценарий начинается с определения некоторых переменных:

<?php

static $strMyMP3Directory = "/home/ed/mp3"; # Укажите реальный каталог MP3-файлов static $strMyDJsEmailAddress = "ed@example.com";

?>

Очевидно, следует заменить e+mail+адрес и вставить путь к каталогу MP3+файлов на Web+сервере, как это было сделано в сценарии генерирования XML+кода.

Загрузить MP3*файлы и поэкспериментировать с ними можно, посетив сайт www.iuma.com. Для редактирования IDv3*тегов можно использовать Winamp (www.winamp.com) ****** MP3*проигрыватель, позволяющий также редактировать IDv3*теги.

Затем подключаются PEAR+объекты. Здесь нет необходимости использовать MP3_ID ++++++ только HTML_Treemenu и вспомогательный компонент:

require_once('HTML/TreeMenu.php'); require_once('xmlhtmltree.phpm');

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

Как только URL создан, содержимое соответствующей страницы извлекается так же, как содержимое файла локальной файловой системы ++++++ PHP достаточно развит, чтобы выполнить такой запрос. Затем полученный XML+вывод передается HTML_TreeMenu+ объекту так же, как в начале главы. Ниже приведен соответствующий фрагмент кода:

$strXMLURL = "http://" . $_SERVER["SERVER_NAME"] . str_replace("request", "generatexml", $_SERVER["SCRIPT_NAME"]);

586 Глава 14

$strXML = implode ('', file($strXMLURL));

$objXMLTree = new XMLHTMLTree("", $strXML); $objXMLTree->GenerateHandOffs(); $objXMLTree->ParseXML();

$objTreeMenu = $objXMLTree->GetTreeHandoff();

Затем подключается условная логика, определяющая поведение сценария при по+ лучении песни, заказанной пользователем. В XML+выводе генерируются ссылки для дерева навигации, которые выглядят следующим образом:

/radiorequest.php?requestfile=9991885931037.mp3

Сценарий radiorequest.php фактически выполняет две функции: он отобража+ ет дерево MP3+файлов, а также сообщение о том, что заказ выполнен успешно. В этом PHP+сценарии необходимо принимать во внимание запросы, в которые включен па+ раметр requestfile, определяющий имя запрашиваемого MP3+файла. Желательно не только знать, что заказ был сделан, но и убедиться в том, что заказ был достовер+ ным. Для этого применяется проверка существования файла:

$requestMade = false; $requestSuccessful = false;

if (!empty($_GET['requestfile'])) { $requestMade = true;

$strRequestFilename = $_GET["requestfile"];

$strFullPath = $strMyMP3Directory . "/" . $strRequestFilename; if (@filesize($strFullPath) > 0) {

Следует отметить, что проверка существования файла выполняется путем опреде+ ления полного пути к нему, после чего определяется его размер с помощью функции filesize. Размер, превышающий единицу, указывает на то, что файл действительно существует. Оператор @ используется потому, что попытка вызывать PHP+функцию filesize для несуществующего файла приводит к генерации неисправимой ошибки, в результате которой выполнение сценария прекращается, а это абсолютно нежелательно.

Если файл существует, то заказ песни считается успешным и сценарий отправляет диджею e+mail+сообщение, используя определенную в начале сценария переменную $strMyDJsEmailAddress, в которой записан необходимый адрес:

$requestSuccessful = true;

// Все работает. Можно отправлять письмо диджею. mail($strMyDJsEmailAddress, "Новый заказ", "Заказана песня. Файл: " .

$strFullPath);

} else {

$requestSuccessful = false;

};

};

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

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

Комбинация переменных $requestMade и $requestSuccessful используется для определения того, какую информацию отображать. Если заказа не было, то сце+ нарий приглашает пользователя сделать заказ и выводит меню, созданное HTML_TreeMenu+компонентом. Если заказ сделан, но выполнить его не удается, выво+ дится поясняющее сообщение и приглашение сделать другой заказ; при этом также выводится HTML_TreeMenu+меню. Если заказ сделан и его можно выполнить, то выво+ дится сообщение с благодарностью, а меню не выводится, потому что в целях данного упражнения предполагается, что пользователь не будет заказывать вторую песню.

PEAR 587

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

Ниже приведен код отображения:

<HTML>

<HEAD>

<SCRIPT LANGUAGE="Javascript" SRC="TreeMenu.js"></SCRIPT> </HEAD>

<BODY>

<H1>Радио PHP</H1> <?php

if ($requestMade) {

?>

<B>Спасибо за заказ!</B> <BR><BR>

<?php

if ($requestSuccessful) {

?>

Ваш заказ принят, мы постараемся как можно быстрее поставить заказанную вами песню.

<?php

} else {

?>

К сожалению, мы не можем поставить заказанную вами песню.Возможно, она была недавно удалена из нашей коллекции. Пожалуйста, попробуйте заказать другую песню.

<?php

};

?>

<BR><BR>

<?php

};

?>

<?php

if (!($requestSuccessful)) {

?>

Закажите песню из приведенного ниже списка. Заказ будет отправлен нашему диджею.

Если песня давно не проигрывалась, то мы включим ее как можно быстрее!

<HR>

<?php $objTreeMenu->printMenu();

?>

<?php

};

?> </BODY> </HTML>

Меню генерируется в точности так же, как в первом примере этой главы. Наконец, следует включить упомянутый в начале HTML+кода JavaScript+файл, не+

обходимый для работы HTML_TreeMenu+компонента.

Резюме

Эта глава знакомит читателя с PEAR ++++++ репозиторием PHP+расширений и приложений.

Вглаве рассматривались темы поиска подходящих пакетов на Web+сайте проекта PEAR,

атакже методика их загрузки и установки; была описана структура проекта PEAR ++++++

588 Глава 14

знание организации репозитория впоследствии должно облегчить поиск необходи+ мых компонентов.

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

Вэтой главе вновь рассматривались PEAR+стандарты написания кода, которых придерживались авторы книги при написании примеров, а также логическое обосно+ вание, лежащее в основе этих стандартов.

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

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

15

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

Одним из самых простых и наиболее распространенных требований к PHP+при+ ложению является возможность отправлять e+mail+сообщения. Электронная почта за очень короткое время стала одним из самых популярных средств коммуникации и PHP, естественно, предоставляет функции для реализации этого средства в приложениях. Детали работы почты в Internet могут быть весьма сложными, и в основном эта слож+ ность исходит не от PHP+программ, а скорее от различных технологий, платформ

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

Прежде чем рассматривать разработку сценариев для отправки e+mail в Windows

иLinux+платформах, следует изучить некоторые технические принципы, лежащие в основе отправки e+mail. Конечно, понимание того, как PHP5 взаимодействует с поч+ товым сервером, весьма важно, и чтобы читателю было проще понять это, в главе приводится пример создания несложного приложения для отправки почты, в кото+ ром используется функция mail(). Наконец, в этой главе рассматривается метод соз+ дания различных типов содержимого e+mail+писем с использованием формата MIME (Multipurpose Internet Mail Extension ++++++ многоцелевое расширение почты в Internet).

Основы e-mail

Чтобы использовать самые распространенные PHP+функции, PHP должен работать в операционной системе (например, Windows или Linux) и иметь доступ к службам Web+ сервера. Для использования e+mail+функций PHP также должен иметь доступ к MTA (Mail Transport Agent ++++++ почтовый транспортный агент), например, к Sendmail, сервер+ ному программному обеспечению, которое отправляет и получает e+mail+сообщения.

Несмотря на то что в PHP существует функция mail(), которая отправляет e*mail, в этом языке нет (на момент написания книги) официальных версий каких* либо PHP*функций или расширений, получающих почту. Расширение mailparse все еще находится в разработке.

590 Глава 15

Чаще всего в PHP используется MTA Sendmail; программист может даже не знать, что на используемом им сервере работает Sendmail ++++++ в сценарии работает функция mail(). В последующем разделе описываются некоторые технические вопросы, свя+ занные с почтовыми протоколами Internet. Однако если читателя главным образом интересует отправка почты и работа почтовой функции, то можно сразу перейти к разделу ‘‘Создание простого PHP+приложения для работы с e+mail’’.

Почтовые протоколы Internet

Как и в случае любого другого вида связи в Internet, в транспортировке почты за+ действован ряд протоколов. Internet+протоколы основываются на документах RFC (Requests For Comment ++++++ запросы на комментарии), которые в случае принятия формируют используемый по обоюдному согласию язык для осуществления связи. Отправка e+mail в Internet основывается на протоколе SMTP (Simple Mail Transfer Pro+ tocol ++++++ простой протокол отправки почты), RFC 821, разработанном Джонатаном Постелом (Jonathan Postel). В 2001 году рабочей группой по информационно+ вычислительным сетям (Network Working Group) была опубликована новая версия RFC 821, RFC 2821 под редакцией Дж. Кленсена (J. Klensen), AT&T Laboratories.

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

В результате этого процесса почта перемещается от одного сервера к другому. Как получить почту от сервера? Для этого предназначены два протокола ++++++ POP3 и IMAP. Прежде чем доставить почту от удаленного сервера, они выполняют проверку реги+ страционной информации пользователя. Это можно представить себе как обычный почтовый ящик, ключ к которому вы передаете другому человеку. Если ключ подхо+ дит, то этот человек сможет доставить вам почту.

Структура e-mail-сообщения

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

В RFC 2822 представлено определение составных частей e+mail+адреса в Internet. (Некоторые RFC можно найти на странице www.faqs.org/rfcs/.) Этот стандарт определяет сообщение как состоящее из US+ASCII+символов, разделенных на строки, каждая из которых завершается символом перевода строки и возврата каретки (CRLF). Поля заголовков представляют собой строки символов, разделенные с помо+ щью специального синтаксиса. За заголовками следует тело сообщения, отделенное от заголовков пустой строкой (строка, в которой нет ничего кроме CRLF).

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

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

Поле заголовка

Описание

 

 

Trace

Включает в себя дату повторной отправки, адрес отправителя, адрес

 

получателя и т.д. Используется, когда сообщение отправляется повторно

 

(например, когда первая попытка доставки не удалась, сервер может

 

попытаться отправить письмо позднее)

From

Обязательное поле. Содержит адрес отправителя. Следует, однако, учесть,

 

что даже если это поле в сообщении присутствует, его точность

 

не гарантируется. Если поле содержит несколько адресов, то в поле

 

Sender должен присутствовать только один адрес. Дата создания

 

включается в данные этого поля. Обратите внимание на заголовок

 

From — это не то же самое поле, что необязательное поле “From:”

Sender

Содержит единственный адрес, с которого отправлено данное письмо

Reply-to

Содержит необязательный адрес для ответа

To

Содержит разделенный запятыми список адресатов

Cc

Содержит разделенный запятыми список адресатов, которым

 

отправляются копии данного сообщения

Bcc

Содержит разделенный запятыми список адресатов, которым

 

отправляются копии данного сообщения, при этом получатели не могут

 

ни увидеть, ни узнать, каким Bcc-получателям отправлялось письмо

Message-id

Необязательное поле, но каждое сообщение должно его содержать.

 

Содержит уникальный идентификатор сообщения

In-reply-to

Необязательное. Один или несколько идентификаторов сообщения

References

Необязательное. Один или несколько идентификаторов сообщения

Subject

Необязательное. Содержит короткую строку, определяющуютему

 

сообщения

Comments

Необязательное. Комментарии о теле сообщения

Keywords

Необязательное. Разделенные запятыми ключевые слова, которые могут

 

оказаться важными для пользователя

Optional

Необязательное. Поле должно лишь соответствовать инструкциям о

 

форматировании, описанным в RFC 2822. Содержимое поля не уточняется

Ниже приводится пример сообщения с заголовками и телом (тело усечено в целях экономии места) в текстовом формате. Это сообщение было получено и отображено как Web+страница, в виде HTML, хотя здесь показан только текст. В заголовке ‘‘From’’ указано имя пользователя почтовой программы (в данном случае mailer@mailer.lindows.com) и да+ та создания письма. В строке ‘‘Received:’’ указан IP+адрес и ‘‘родословная’’ e+mail+ сообщения. Кроме этого в письме есть строки ‘‘To:’’, ‘‘Date:’’, ‘‘From:’’ и ‘‘Subject:’’ (заголовок ‘‘From:’’ с двоеточием ++++++ не то же самое, что ‘‘From’’ в начале сообщения).

From mailer@mailer.lindows.com Thu Jan 22 17:52:58 2004 Received: from [130.94.123.236] (helo=mailer.lindows.com)

by mail1.servata.com with esmtp (Exim 3.35 #1 (Debian))

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