- Saved searches
- Use saved searches to filter your results more quickly
- License
- optimumweb/php-email-reader-parser
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- Чтение почты через IMAP в PHP
- Получение писем
- Установка флагов
- Удаление писем
- How to Read Emails Using PHP
- 1. Open IMAP Stream: imap_open()
- 2. Get Emails: imap_search()
- 3. Header of Email Message
- 4. Body of Email Message
- 5. Structure of Message
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
PHP Email Reader (using IMAP) and Parser (using mimeDecode)
License
optimumweb/php-email-reader-parser
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
It does something that should be so simple but turns out to be very complex using PHP: reading emails from a mailbox using IMAP and then parsing the returned emails into a dev-friendly object.
- PHP 5.4+
- PHP PEAR
- PHP IMAP extension
- PHP mbstring extension (mb_convert_encoding)
Simply require both classes (Email_Reader and Email_Parser) inside your code.
require_once('PATH_TO_FILES/email_reader.php'); require_once('PATH_TO_FILES/email_parser.php'); ?>
- Note that you can use the Email_Parser class by itself without the Email_Reader class, but not the other way around.
Email_Reader is used to open an IMAP stream to a mailbox and then fetch messages.
$reader = new Email_Reader($mailbox, $username, $password); $messages = $reader->get_messages(); $unread = $reader->get_unread(); ?>
Email_Parser is used within Email_Reader to be able to decode the returned emails. It can also be used by itself to read emails, for example, from php://std in the case of email piping.
#! /usr/bin/php -q $fd = fopen("php://stdin", "r"); $raw = ""; while ( !feof($fd) ) < $raw .= fread($fd, 1024); > fclose($fd); $email = new Email_Parser($raw); doWhaterever($email->from, $email->subject, $email->body); ?>
In order to write these classes, I had a lot of reading of other people’s work and I would like to thank the following repository owners.
Jonathan Roy, web developper at OptimumWeb
Чтение почты через IMAP в PHP
В PHP без проблем можно работать с почтой через IMAP, для этого есть все необходимые функции, подробнее на php.net.
Получение писем
$imap = imap_open(«адрес», «e-mail», «пароль») – создает подключение к почтовому ящику. Далее, функция imap_search($imap, ‘ALL’) получает массив c индикаторами писем.
ALL | Все сообщения |
UNSEEN | Непрочитанные сообщения |
SEEN | Прочтенные сообщения (установлен флаг seen) |
NEW | Новые сообщения (впервые появилось в ящике в ходе текущей сессии) |
OLD | Старые сообщения |
ANSWERED | Сообщения с флагом answered (отвеченный) |
UNANSWERED | Неотвеченные сообщения |
DELETED | Удаленные сообщения |
UNDELETED | Не удаленные сообщения |
FLAGGED | Сообщения с установленным флагом flagged (важное) |
RECENT | Сообщения с флагом recent (недавнее сообщение) |
UNFLAGGED | Сообщения без установленных флагов |
ON «date» | Сообщения с датой, равной « date » |
BEFORE «date» | Сообщения с датой, до « date » |
SINCE «date» | Сообщения с датой, после « date » |
FROM «string» | Сообщения в поле From: которых присутствует «string » |
TO «string» | Сообщения в поле To: которых присутствует «string » |
SUBJECT «string» | Сообщения, у которых присутствует «string » в поле Subject |
BODY «string» | Сообщения содержащие «string » в теле |
TEXT «string» | Сообщения с текстом «string » |
KEYWORD «string» | Сообщения с ключевым словом «string» |
UNKEYWORD «string» | Сообщения, не имеющие ключевого слова «string » |
Далее массив обрабатывается в цикле, в примере происходит обход по всем письмам.
$imap = imap_open("INBOX", "mail@test.ru", "Пароль"); $mails_id = imap_search($imap, 'ALL'); foreach ($mails_id as $num) < // Заголовок письма $header = imap_header($imap, $num); var_dump($header); // Тело письма $body = imap_body($imap, $num); var_dump($body); >imap_close($imap);
$header = imap_header($imap, $num) – получает заголовки письма в виде объекта. Для удобства можно преобразовать в массив:
$header = imap_header($imap, $num); $header = json_decode(json_encode($header), true); print_r($header);
Array( [date] => Mon, 16 Sep 2019 16:03:56 +0300 [Date] => Mon, 16 Sep 2019 16:03:56 +0300 [subject] => =?UTF-8?B?SGVsbyBXb3JsZA==?= [Subject] => =?UTF-8?B?SGVsbyBXb3JsZA==?= [message_id] => [toaddress] => mail@snipp.ru [to] => Array( [0] => Array( [mailbox] => mail [host] => snipp.ru ) ) [fromaddress] => =?UTF-8?B?MTIzNDU2QHNpdGUucnU=?= [from] => Array( [0] => Array( [personal] => =?UTF-8?B?MTIzNDU2QHNpdGUucnU=?= [mailbox] => 123456 [host] => site.ru ) ) [ccaddress] => [cc] => [reply_toaddress] => [reply_to] => [senderaddress] => [sender] => [Recent] => [Unseen] => [Flagged] => [Answered] => [Deleted] => [Draft] => [Msgno] => 1 [MailDate] => 16-Sep-2019 16:03:59 +0300 [Size] => 38895 [udate] => 1568639039 )
Как видно в примере, тема письма и другие данные закодированы в base64 ( ?UTF-8?B?SGVsbyBXb3JsZA==?= ), декодировать их можно с помощью функции mb_decode_mimeheader() .
$header = imap_header($imap, $num); $header = json_decode(json_encode($header), true); echo mb_decode_mimeheader($header['subject']);
$body = imap_body($imap, $num) – тело письма, обычный текст.
Может быть закодировано в quoted-printable (= D0=94=D0=BE=D0=B1=D1=80=D1=8B=D0=B9 ), раскодировать можно функцией quoted_printable_decode() .
$body = imap_body($imap, $num); $body = quoted_printable_decode($body); echo $body;
Установка флагов
imap_setflag_full ($imap, $num, $flag) – установит письму флаг, возможны значения:
seen | Сообщение прочитано |
answered | На сообщение отправлен ответ |
flagged | Сообщение отмечено как «важное» |
deleted | Сообщение отмечено как удалённое |
draft | Сообщение отмечено как черновик |
recent | Недавнее сообщение |
Можно установить сразу несколько флагов, разделяя их пробелами.
В примере, письмам, у которых в теме письма есть слово «заявка» устанавливается флаг «важное».
$imap = imap_open("INBOX", "mail@test.ru", "Пароль"); $mails_id = imap_search($imap, 'ALL'); foreach ($mails_id as $num) < // Заголовок письма $header = imap_header($imap, $num); $header = json_decode(json_encode($header), true); $subject = mb_decode_mimeheader($header['subject']); if (mb_strpos($subject, 'заявка') !== false) < imap_setflag_full($imap, $num, '\\flagged'); >> imap_close($imap);
Удаление писем
В цикле, письмо помечается функцией imap_delete() , после этого вызывается функция imap_expunge() , которая выполняет удаление всех помеченных писем.
$imap = imap_open("INBOX", "mail@site.ru", "Пароль"); $mails_id = imap_search($imap, 'ALL'); foreach ($mails_id as $num) < $header = imap_header($imap, $num); $body = imap_body($imap, $num); // Помечаем письмо как удаленное imap_delete($imap, $num); >// Удаление помеченных писем imap_expunge($imap); imap_close($imap);
How to Read Emails Using PHP
- PHP How To
You can connect to an email inbox using PHP’s IMAP functions. First, you need to open an IMAP stream to a mailbox.
1. Open IMAP Stream: imap_open()
$inbox = imap_open($mailbox, $username, $password) or die('Cannot connect to email: ' . imap_last_error());
The $mailbox string consists of a server and a mailbox path on this server. The server part is enclosed in curly brackets ». It consists of the server’s name or IP address, an optional port (prefixed by ‘:’), and an optional protocol specification (prefixed by ‘/’).
For example, to connect to an SSL IMAP with a self-signed certificate, add /ssl/novalidate-cert after the protocol specification:
2. Get Emails: imap_search()
This function searches the mailbox currently opened in the IMAP stream and returns an array of messages matching the given search criteria. For example, to return all the messages:
$emails = imap_search($inbox, 'ALL');
To put the newest emails on top:
If emails are returned, you can cycle through each email:
if($emails)
rsort($emails);
foreach($emails as $msg_number)
// Get email headers and body
>
>
3. Header of Email Message
The function imap_headerinfo() is used to read the header of email of the given message number. For example,
$header = imap_headerinfo($inbox, $msg_number);
This function returns FALSE on error or, if successful, the information as an object.
- $header->date
- $header->subject
- $header->toaddress
- $header->to: Array of objects with properties: personal, adl, mailbox, and host
- $header->fromaddress
- $header->from: Array of objects with properties: personal, adl, mailbox, and host
- $header->reply_toaddress
- $header->reply_to: Array of objects with properties: personal, adl, mailbox, and host
- $header->Size: The message size
- $header->udate: Mail message date in Unix time
To get the name and email from address properties:
$from = $header->from;
foreach ($from as $id => $object)
$fromname = $object->personal;
$fromaddress = $object->mailbox . "@" . $object->host;
>
4. Body of Email Message
The imap_body() function reads and returns the body of the message. For example,
$message = imap_body($inbox, $msg_number);
This function returns a verbatim copy of the message body. To extract single parts of a multipart MIME-encoded message, you have to use imap_fetchstructure() to analyze its structure and imap_fetchbody() to extract a copy of a single body component.
The imap_fetchbody() gets a particular section of the body of the message. It returns a particular section of the body of the specified messages as a text string. Body parts are not decoded by this function. For example,
$message = imap_fetchbody($inbox, $msg_number, $part_number);
5. Structure of Message
The imap_fetchstructure() function fetches all the structured information for a given message. For example,
$s = imap_fetchstructure($inbox, $msg_number);
This function returns an object. The email can be a simple message or multipart message.
if (!$s->parts) // Simple message
getpart($inbox, $msg_number, $s, 0);
>
else // Multipart message: cycle through each part
<
foreach ($s->parts as $part_n => $p)
getpart($inbox, $msg_number, $p, $part_n + 1);
>
>
For simple message, part number is 0 and email body is fetched using imap_body().
Function to get part of a message:
public function getpart($mbox, $mid, $p, $part_n)
$data = ($part_n) ? imap_fetchbody($mbox, $mid, $part_n) : imap_body($mbox, $mid);
// Decode
if ($p->encoding == 4)
$data = quoted_printable_decode($data);
>
else if ($p->encoding == 3)
$data = base64_decode($data);
>
// Email Parameters
$eparams = array();
if ($p->parameters)
foreach ($p->parameters as $x)
$eparams[strtolower($x->attribute)] = $x->value;
>
>
if ($p->dparameters)
foreach ($p->dparameters as $x)
$eparams[strtolower($x->attribute)] = $x->value;
>
>
// Attachments
if ($eparams['filename'] || $eparams['name'])
$filename = ($eparams['filename']) ? $eparams['filename'] : $eparams['name'];
$this->attachments[$filename] = $data;
>
// Text Messaage
if ($p->type == 0 && $data)
if (strtolower($p->subtype) == 'plain')
$this->plain_msg .= trim($data) ."\n\n";
>
else
$this->html_msg .= $data . '
';
>
$this->charset = $eparams['charset'];
>
else if ($p->type == 2 && $data)
$this->plain_msg .= $data. "\n\n";
>
// Subparts Recursion
if ($p->parts)
foreach ($p->parts as $part_n2 => $p2)
self::getpart($mbox, $mid, $p2, $part_n . '.' . ($part_n2 + 1));
>
>
>
Join for Tips and Updates