How to Read Emails Using PHP
PHP How ToYou 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 '{' and '}'. 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:
$mailbox = "{localhost:993/imap/ssl/novalidate-cert}INBOX";
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:
rsort($emails);
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 . '<br><br>';
}
$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));
}
}
}