Posts tagged ‘IMAP’

PHP IMAP Notes

Previously I wrote about using PHP’s IMAP functions. Now I’d like to provide a more detailed, and less wordy, overview of some of the more common IMAP functions. Enjoy!

imap_open

imap_open opens a connection to the specified mailbox. It takes up to 5 parameters:

Mailbox:
This is the address and port of the mail server you are connecting to. Typically this parameter will look like one of the following:

  • mail.domain.net:143
  • localhost
  • 127.0.0.1:110

The port number is optional, but it is much more efficient if one is provided. The default IMAP port is 143 and POP3 is 110

Username
Typically the email address you are trying to access mail from, but not necessarily.

Password
The password corresponding to the username

Options
The options, or flags, modify your connection stream. The default is /imap but I’ve found that /imap/novalidate-cert is often necessary. If you are trying to connect using POP3 you’ll have to set this to /pop3.

Retries
The number of connection retries. If your mail server limits the number of connection attempts it is important that this value be set to 0, otherwise you may lock yourself out of your account.

Don’t forget to close the connection stream using imap_close($mailbox) where mailbox is the connection stream you opened with imap_open.

imap_fetch_overview

imap_fetch_overview returns an overview of one or more emails. This function Always returns an array, even if only a single message is specified.

imap_stream
A connection stream created with imap_open

message id or sequence
imap_fetch_overview takes either a single message id, or a sequence formatted as x:y (ex. 1:5 will return message 1 through 5 inclusive).

Options
This parameter must be set to FT_UID if the sequence parameter is a sequence of UIDs rather than message ids. Using UIDs is often preferable to message ids because message ids are not guaranteed to remain the same. Some functions however, require that you use message ids.

This function returns a lot of useful information about a particular email. Read the function documentation for a full list. While this function does return to and from headers, it does not return the cc and bcc headers. You will have to use imap_headerinfo to obtain these. Note that imap_headerinfo cannot take a UID as a message parameter, you’ll have to use message ids.

imap_check

This function returns information about the specified mailbox. Most likely if you are using this function, you are using it to obtain the number of messages in the mailbox.

Setting and Unsetting Message Flags

Each message in a mailbox has a set of flags, probably the most interesting one is the SEEN flag. The seen flag indicates if the email has been opened or read. Usually this flag is set when using the imap_body function to obtain the body of a message. If you want to mark an email as seen you can use imap_setflag_full. To set the email as unread, use imap_clearflag_full to unset the SEEN flag.

Deleting Emails

The imap_delete flags an email for deletion. This function is really a shortcut for calling imap_setflag_full with the deleted flag. Likewise, imap_undelete is a shortcut for calling imap_clearflag_full with the deleted flag. Note that these functions do not actually delete the message. In order to delete the message you must either call imap_expunge or imap_close with the optional flag CL_EXPUNGE.

Searching the mailbox

The imap_search function is great for emails that meet a certain criteria. Personally I use this function mostly to find unopened emails.

Accessing Email through IMAP using PHP

For a concise overview of some of the more common functions and a few tips read PHP IMAP Notes.

Previously I wrote about Intercepting Email with PHP and so far, that has been the most popular post on this blog. That being the case, I decided to write about how you can use PHP’s IMAP functions to access email.

The main difference between the two method is that when accessing email through IMAP you are accessing a mailbox that already exists. If you use piping to intercept an email you bypass the mailbox altogether. One advantage of using PHP’s IMAP functions to access Email is that you can avoid working with raw data, which would be the case with piping. With the functions provided by PHP, there would be nothing to stop you from building a webmail application with just as many capabilities as any of the major applications out there.

Before you can retrieve your email you must establish a connection to the mailbox. In order to do this you will need the IP and port of the mail server, along with a valid username and password. To connect to a mailbox on your local host use this code:

$host = 'localhost:143';
$user = 'user@domain.com';
$password = 'drowssap';
$mailbox = "{$host}INBOX";

$mbx = imap_open($mailbox , $user , $password);

Note that port 143 is the default, but is not always the correct port. If you don’t know the port you can use just the IP (or localhost) by itself, though it is recommended that you find the correct port. Also note that you can use this code to open a POP stream, as well as many other protocols. I’ll show you how to open a POP stream here, but for other protocols (IMAP over SSL, NNTP, etc.) you’ll have to read the documentation for imap_open.

$pophost = 'localhost:110/pop3';
$user = 'user@domain.com';
$password = 'drowssap';
$mailbox = "{$host}INBOX";

$mbx = imap_open($mailbox , $user , $password);

In this case as well, port 110 is the default but might not be the case for you.

Now that we’ve opened our IMAP (or other) stream we can start using PHP’s various IMAP functions to work with our mailbox. Note that if you’re stream is not an IMAP stream, not all of these functions will work as intended. Here I will show you to retrieve all of the emails in your inbox and how to view one of those emails, but I will only be using a small portion of the functions available to you, so you may want to take a look at the functions.

<?php
$mbx = imap_open($mailbox , $user , $password);

/*imap_check returns information about the mailbox
including mailbox name and number of messages*/
$check = imap_check($mbx);

/*imap_fetch_overview returns an overview for a message.
An overview contains information such as message subject,
sender, date, and if it has been seen. Note that it does
not contain the body of the message. Setting the second
parameter to "1:n" will cause it to return a sequence of messages*/
$overviews = imap_fetch_overview($mbox,"1:{$check->Nmsgs}");
?>
<table>
     <tr>
          <td>From</td>
          <td>Date</td>
          <td>Subject</td>
     </tr>

<?php
foreach($overviews as $overview)
{
     ?>
     <tr>
          <td><?php echo $overview->from; ?></td>
          <td><?php echo $overview->date; ?></td>
          <td><a href="open.php?id=<?php echo $overview->uid; ?>"><?php echo $overview->subject; ?></a></td>
     </tr>
     <?php
}
?>
</table>

The code above will generate a list of emails in your inbox, similar to what you would see if you logged into your email account. Each subject line is a link to open.php which is an arbitrary script that will open the message with the corresponding uid. The code below is an example of what open.php might look like:

<?php
$uid = $_GET['id']; //I won't validate this input, but you should

$mbx = imap_open($mailbox , $user , $password);
$overview = imap_fetch_overview($mbx, $uid, FT_UID);
$body = imap_body($mbx, $uid, FT_UID);
?>
<table>
     <tr>
          <td>From:</td>
          <td><?php echo $overview->from; ?></td>
     </tr>
     <tr>
          <td>Date:</td>
          <td><?php echo $overview->date; ?></td>
     </tr>
     <tr>
          <td>Subject:</td>
          <td><?php echo $overview->subject; ?></td>
     </tr>
     <tr>
          <td colspan="2"><?php echo $body; ?></td>
     </tr>
</table>

Notice that I set the FT_UID parameter in order to use a UID rather than a message_id. A UID will always remain the same, while a message_id may change as the content of the mailbox changes. The script would most likely work with message ids, but UIDs are guaranteed to work. If you are using a POP stream, you might find that in some cases you have to use message_ids in place of UIDs due to compatibility issues.

The imap_body function returns the body of the message with the corresponding id, but it also sets the message to “seen”. If you do not want to mark the message as seen, pass it the FT_PEEK option.

There is a great deal that you can do with these functions; far too much for me to detail all of it here. If there is anything in particular you would like to see, feel free to post a comment detailing your question.