Some friends of mine publish a literary journal that accepts submissions via email. At their request I wrote a script to download messages from the journal's Gmail account and do some simple parsing tasks. Most of the submissions are made using an HTML form and a corresponding mailer script on their website, so I knew the precise format of the incoming messages (see Figure 1). What I didn't know was how to access Gmail in PHP.



Click here for larger image

Figure 1. Format of Incoming Submission Messages

After wasting some time fussing with libgmailer, an unofficial Gmail API, I had a "D'oh!" moment: I realized that all I really needed were the IMAP functions built into PHP 4 and up. In this article I will demonstrate how to use the PHP IMAP functions to download and parse Gmail messages.

The Setup

For the IMAP functions to work, the IMAP extension needs to be installed on your server. You can check the installation status with a call to phpinfo(), which prints information about your server's PHP setup.
To access Gmail messages, you must also enable IMAP for your Gmail account:
  1. Log into Gmail and select Settings.
  2. Select the Forwarding and POP/IMAP tab.
  3. Select Enable IMAP and save your changes.

The PHP IMAP Functions

Now for the code. The following IMAP functions are used in this example:
The following sections discuss each of these functions.

imap_open()

This function opens an IMAP stream to a mailbox.
   $mbox = imap_open($mailbox, $username, $password);
The $username and $password parameters obviously are the username and password for the account. For a Gmail account, the username is the user's full email address, e.g. myaccount@gmail.com.
What's not immediately obvious is what to use for the $mailbox parameter. It's a string parameter with a special format. I also had a special requirement. In Gmail, you use labels to group related emails rather than filing them in folders. I wanted to access only those messages with the label "Current Batch" (see Figure 2).



Click here for larger image

Figure 2. Gmail Labels for Group Related Emails

The value of $mailbox is set as follows:
   $mailbox = '{imap.gmail.com:993/ssl/novalidate-cert}Current Batch';
The first part of the string consists of the server information inside curly braces. (To get the server name and port number, I clicked on the Configuration instructions link on the same Gmail screen where I enabled IMAP, and then clicked on Other.)
Gmail requires an SSL connection for IMAP access, so you also need to include the /ssl flag after the port number. The /novalidate-cert flag tells the function not to bother validating the SSL server's certificate. In addition, there are several other flags you can specify, such as /readonly for a read-only connection. (See the IMAP manual on php.net for the full list.)
After the curly braces, you can optionally specify the mailbox name. The default is INBOX. You can also use a label such as "Current Batch" to specify a set of labeled messages within your Gmail Inbox.

imap_num_msg()

This function returns the number of messages in the mailbox, which is useful for looping.
   $n = imap_num_msg($mbox);

imap_header_info()

This function returns an object containing header information for a given message. It takes the mailbox object and the message number as parameters. The message numbers start with 1, so your loop might look something like this:
for ($i = 1; $i <= $n; $i++) {      
      $header = imap_headerinfo($mbox, $i);
      . . .
}
When you have the object, you can get the header information from its properties, such as from, date and subject.

imap_body()

This function returns the body of the message as a string. Like imap_header_info(), it takes the mailbox object and the message number as parameters.
$body = imap_body($mbox, $i);

imap_close()

This function closes the IMAP stream. It takes the mailbox as a parameter.
imap_close($mbox);

Where to Go from Here

Within your loop you can process individual messages. The example script in the first section ($mbox = imap_open($mailbox, $username, $password);) simply echoes the message contents, but if you know how the message body is formatted you can parse it and do something more useful with the information. If you really want to get fancy you can work with multipart MIME-encoded messages using imap_fetchstructure() and imap_fetchbody().
You'll also should implement better security. I know you know this already, but I'll make it the last word anyway: don't hardcode your Gmail username and password in your script and then upload your script to a location where anyone can run it.

About the Author

Rose Kelleher is a freelance writer. to e-mail her.