В первой части этой серии я обсудил, как подключаться к серверам IMAP с помощью расширения PHP IMAP. В этой части мы закончим серию, обсуждая работу с папками и чтение содержимого электронной почты. Давайте начнем!
Работа с флагами электронной почты
С каждым сообщением обычно связан список флагов: непрочитанный, отвеченный, помеченный, черновик и т. Д. Мы можем проверить свойство сообщения « Unseen
Если сообщение было просмотрено, мы получим значение «U». Итак, возвращаясь к коду из первой части, давайте изменим его, чтобы показать состояние чтения / непрочитанного.
<?php
$numMessages = imap_num_msg($imap);
for ($i = $numMessages; $i > ($numMessages - 20); $i--) {
$header = imap_header($imap, $i);
...
$uid = imap_uid($imap, $i);
$class = ($header->Unseen == "U") ? "unreadMsg" : "readMsg";
echo "<ul class="' . $class . '">';
echo "<li><strong>From:</strong>" . $details["fromName"];
echo " " . $details["fromAddr"] . "</li>";
echo "<li><strong>Subject:</strong> " . $details["subject"] . "</li>";
echo '<li><a href="mail.php?folder=' . $folder . '&uid=' . $uid . '&func=read">Read</a>';
echo " | ";
echo '<a href="mail.php?folder=' . $folder . '&uid=' . $uid . '&func=delete">Delete</a></li>';
echo "</ul>";
}
Мы можем проверить состояние свойства Unseen
.unreadMsg {
color: #000;
font-weight: bold;
}
.readMsg {
color: #999;
}
Мы также можем создавать специальные флаги на электронные письма. Например, допустим, мы хотели пометить сообщение как помеченное. Для этого мы используем свойство Flagged
<?php
if ($header->Flagged == "F") {
$class .= " flaggedMsg";
}
Чтобы установить флаги для сообщения, мы используем impa_setflag_full()
<?php
$status = imap_setflag_full($imap, $uid, "\Seen \Flagged", ST_UID);
Приведенный выше код помечает сообщение как «Read (\ Seen)» и устанавливает помеченный статус на «F». Я всегда предпочитаю использовать UID вместо порядкового номера электронной почты в качестве второго параметра, поэтому я должен установить необязательный четвертый параметр с константой ST_UID
С помощью этой функции вы также можете указать другие флаги, такие как Черновик, Удаленный и Ответ.
Хотя я установил флаги только для одного сообщения, вы можете указать диапазон, например «1,10», в качестве второго параметра для установки флагов для нескольких сообщений, если хотите.
Удаление сообщений электронной почты
Функция imap_delete()
Он помечает их для удаления, но фактически не удаляет их из вашей учетной записи. Функция imap_expunge()
<?php
imap_delete($imap, $uid, FT_UID);
imap_expunge($imap);
Я вызвал функцию удаления с UID вместо порядкового номера. В противном случае я рискую потерять важные сообщения из-за изменения порядковых номеров (помните из первой части, что порядковые номера не являются уникальными).
Просмотр вложений электронной почты
Помимо чтения и отправки электронных писем, работа с вложениями электронной почты, вероятно, является следующей наиболее важной функцией почтового клиента. Мы сосредоточимся на проверке вложений электронной почты, их отображении и загрузке.
Существуют различные методы для чтения структуры сообщения и идентификации вложений. Библиотека, упомянутая в первой части, класс Receive Mail, разработанный Mitul Koradia, также имеет функции для их загрузки. Но здесь я буду использовать функции, включенные в раздел комментариев для функции imap_fetchstructure()
Прежде чем взглянуть на некоторый код, я хотел бы показать вам структуру электронного письма с вложениями, возвращаемую imap_fetchstructure()
stdClass Object ( [тип] => 1 [кодировка] => 0 [ifsubtype] => 1 [subtype] => MIXED [ifdescription] => 0 [ifid] => 0 [ifdisposition] => 0 [ifdparameters] => 0 [ifparameters] => 1 [параметры] => массив ( [0] => stdClass Object ( [attribute] => ГРАНИЦА [значение] => bcaec54b516462cef304c7e9d5c3 ) ) [parts] => Массив ( [0] => stdClass Object ( [тип] => 1 [кодировка] => 0 [ifsubtype] => 1 [subtype] => АЛЬТЕРНАТИВА [ifdescription] => 0 [ifid] => 0 [ifdisposition] => 0 [ifdparameters] => 0 [ifparameters] => 1 [параметры] => массив ( [0] => stdClass Object ( [attribute] => ГРАНИЦА [значение] => bcaec54b516462ceeb04c7e9d5c1 ) ) [parts] => Массив ( [0] => stdClass Object ( [тип] => 0 [кодировка] => 0 [ifsubtype] => 1 [subtype] => PLAIN [ifdescription] => 0 [ifid] => 0 [линии] => 1 [bytes] => 2 [ifdisposition] => 0 [ifdparameters] => 0 [ifparameters] => 1 [параметры] => массив ( [0] => stdClass Object ( [attribute] => CHARSET [значение] => ISO-8859-1 ) ) ) [1] => stdClass Object ( [тип] => 0 [кодировка] => 0 [ifsubtype] => 1 [subtype] => HTML [ifdescription] => 0 [ifid] => 0 [линии] => 1 [байтов] => 6 [ifdisposition] => 0 [ifdparameters] => 0 [ifparameters] => 1 [параметры] => массив ( [0] => stdClass Object ( [attribute] => CHARSET [значение] => ISO-8859-1 ) ) ) ) ) [1] => stdClass Object ( [тип] => 3 [кодировка] => 3 [ifsubtype] => 1 [subtype] => ZIP [ifdescription] => 0 [ifid] => 0 [bytes] => 115464 [ifdisposition] => 1 [disposition] => ПРИЛОЖЕНИЕ [ifdparameters] => 1 [dparameters] => Массив ( [0] => stdClass Object ( [attribute] => FILENAME [value] => weekly-reports.zip ) ) [ifparameters] => 1 [параметры] => массив ( [0] => stdClass Object ( [attribute] => NAME [value] => weekly-reports.zip ) ) ) ) )
Если вы внимательно посмотрите на конструкцию, вы увидите вложение как часть с disposition
Это письмо имеет 1 вложение, но вполне возможно иметь несколько вложений и, следовательно, несколько частей с «ATTACHMENT». Мы можем легко идентифицировать вложения, проверив этот параметр.
<?php
$mailStruct = imap_fetchstructure($imap, $i);
$attachments = getAttachments($imap, $i, $mailStruct, "");
Внутри функции viewMailbox()
Сначала мы получаем структуру каждого письма с помощью функции imap_fetchstructure (). Он вернет объект, подобный показанному ранее. Затем мы вызываем getAttachments()
<?php
function getAttachments($imap, $mailNum, $part, $partNum) {
$attachments = array();
if (isset($part->parts)) {
foreach ($part->parts as $key => $subpart) {
if($partNum != "") {
$newPartNum = $partNum . "." . ($key + 1);
}
else {
$newPartNum = ($key+1);
}
$result = getAttachments($imap, $mailNum, $subpart,
$newPartNum);
if (count($result) != 0) {
array_push($attachments, $result);
}
}
}
else if (isset($part->disposition)) {
if ($part->disposition == "ATTACHMENT") {
$partStruct = imap_bodystruct($imap, $mailNum,
$partNum);
$attachmentDetails = array(
"name" => $part->dparameters[0]->value,
"partNum" => $partNum,
"enc" => $partStruct->encoding
);
return $attachmentDetails;
}
}
return $attachments;
}
Сначала мы проверяем, установлены ли части для текущего электронного письма, а затем мы должны рекурсивно пройти через каждую часть. Мы должны изменить номер детали и передать его на рекурсивный вызов. Как видите, номера подразделов разбиты на точечные сегменты. Если у вас есть 3 уровня номера детали, это будет что-то вроде 1.0.1.
Когда другие детали недоступны, мы проверяем, доступен ли параметр утилизации и имеет ли он значение «ATTACHMENT». В таких ситуациях мы получаем структуру данной части, используя imap_bodystruct()
И imap_bodystruct()
imap_fetchstructure()
Единственное различие между ними состоит в том, что мы можем использовать imap_bodystruct()
Теперь у нас есть список сведений о вложениях для данного письма, и мы перебираем все вложения и отображаем ссылки для их загрузки:
<?php
echo "Attachments: ";
foreach ($attachments as $attachment) {
echo '<a href="mail.php?func=' . $func . '&folder=' . $folder . '&uid=' . $uid .
'&part=' . $attachment["partNum"] . '&enc=' . $attachment["enc"] . '">' .
$attachment["name"] . "</a>";
}
Загрузка приложений
Чтобы загрузить вложение, нам нужны UID электронной почты, номер детали и тип кодировки вложения. Я включил эти параметры в ссылку для скачивания, созданную выше. После нажатия на ссылку можно вызвать следующую функцию:
<?php
function downloadAttachment($imap, $uid, $partNum, $encoding, $path) {
$partStruct = imap_bodystruct($imap, imap_msgno($imap, $uid), $partNum);
$filename = $partStruct->dparameters[0]->value;
$message = imap_fetchbody($imap, $uid, $partNum, FT_UID);
switch ($encoding) {
case 0:
case 1:
$message = imap_8bit($message);
break;
case 2:
$message = imap_binary($message);
break;
case 3:
$message = imap_base64($message);
break;
case 4:
$message = quoted_printable_decode($message);
break;
}
header("Content-Description: File Transfer");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=" . $filename);
header("Content-Transfer-Encoding: binary");
header("Expires: 0");
header("Cache-Control: must-revalidate");
header("Pragma: public");
echo $message;
}
Сначала нам нужно получить структуру данной части, чтобы идентифицировать имя вложения, что делается с помощью imap_bodystruct()
Вы можете видеть, что я использовал imap_msgno(
это потому, что imap_bodystruct () не принимает UID, поэтому мы должны преобразовать UID в порядковый номер.
Затем мы получаем содержимое вложения с помощью imap_fetchbody()
Он будет получать только содержимое данного номера детали. Затем мы используем соответствующую функцию декодирования контента в соответствии с типом кодирования данного вложения для его декодирования.
Наконец, мы выводим содержимое вложения с соответствующими заголовками, чтобы браузер загрузил файл.
Резюме
Мы завершили наш взгляд на функции IMAP в PHP, и теперь у вас должно быть достаточно понимания, чтобы собрать простую работающую программу чтения электронной почты. Обязательно узнайте о других доступных функциях и изучите их, чтобы расширить свое понимание.
Изображение через Fotolia