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.

images/articles/php/read-emails-using-php.jpg

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));
}
}
}