http://www.developer.com/

Back to article

Web mail in PHP


April 16, 1999

Asked to write an article about Apache and PHP, I had to take a moment to come up with a good sample application to demonstrate the beauty of Apache and PHP. It had to be something that I would personally like to use but simple enough for educational purposes, and something at least marginally original.

A Web-based e-mail interface may not be a very original idea, nor is my humble example any match for the more advanced Web mail applications that already exist, but I'm likely to need such an interface at some point and it makes an excellent topic for showing off what you can do with PHP. So Web mail it is.

What is PHP?

In short, PHP is a server-side programming environment that lets you mix HTML and script code. The scripting language resembles Perl and if you know a little Perl or C you will find it quite easy to get started using PHP. Since PHP was specifically designed to be a server-side scripting language for Web servers, it offers a vast array of functions and behind-the-scenes magic to make common tasks easy. For instance, data entry fields in forms will automagically turn up as PHP variables that use the same names as the form fields etc.

PHP also supports a number of databases, ranging from big names like Oracle, Sybase and Informix to smaller database systems like MySQL -- the latter being perhaps the most popular database to use in conjunction with PHP.

Enough talk!

I'm sure you're dying to get a taste, so let's jump right into some simple code.

As I mentioned earlier PHP lets you mix HTML and script code. Now what does this look like in practice? Consider the following stripped-down file:

   <TITLE>Sample PHP script</TITLE>
   <H1>Date sample</H1>

   <?PHP
     $today = date("Y-m-d");
     print "Today's date is $today\n";
   ?>

   The above date was printed by PHP.

As you can see, we start out with some standard HTML code. We provide a title for the page and a heading. Then we encounter section of the document enclosed within "<?PHP" and "?>". These are called SGML processing tags -- this is how we tell the Web server where there's code that we wish to run.

The code doesn't do much. First it calls the

date()
function with some parameters to tell it how we would like the current date formatted. The result of
date()
is assigned to variable
$today
and on the next line we print the result.

Forming content

As mentioned earlier, PHP was specifically designed as a server-side scripting language to make life easier for Web developers. Something a lot of people ask about is how to handle FORM content, so let's see how that can be done in PHP. Consider the following HTML code that contains a form:
   <TITLE>Form example</TITLE>
   <FORM ACTION=formhandler.php3 METHOD=GET>
      Name: <INPUT TYPE=text NAME=name VALUE=""><BR>
     Email: <INPUT TYPE=text NAME=email VALUE=""><BR>

     <INPUT TYPE=submit>
   </FORM>

The ACTION parameter points to a file with the peculiar suffix

php3
. This is the file containing the code that handles the form content when we click the submit button. The code for this handler might be something like this:
   <TITLE>Form handler example</TITLE>
   Mailing the data to the webmaster:

   <?PHP
      $message = "Name: $name\nEmail: $email\n";
      mail("your-email-here", "Form feedback", $message);
      print "The following data was sent:\n $message";
   ?>

Remember that we had two input fields in our form, named "name" and "email"? The values we typed into these input fields are now assigned to PHP variables with the same names as the form input fields and we can manipulate them just like any other variable. In this particular case we combine them into a string and use a built-in function to mail the data to the Webmaster.

Going from here to there

We could spend all afternoon looking at cute little examples like that, but that's probably not why you came. You're wondering whether this PHP thing can be used for something useful and worthwhile.





Now for the simple Web interface to a mail system. There are a number of ways to do this. We could write a system that runs with superuser privileges, mucks about with people's files directly, and totally ignores the fact that people actually have invented several different kinds of wheels already. But we won't. We'll use IMAP, also known as the Internet Message Access Protocol.

Mapping the interface

Why IMAP? Well, first of all IMAP is an open standard. The specs are publicly available to anyone and there are several implementations available in source code form. This means more developers can make IMAP-enabled software, which in turn gives the user more choice.

Second, IMAP is well suited to manage mailboxes on remote hosts rather than merely fetching mail to a local machine. With IMAP you can list mailboxes, copy or move mail between them, and request parts of multipart e-mail messages -- all on the server machine.

The idea here is that the user can use the Web interface if she likes to, but she can also access the same e-mail through her mail client. Using her favorite mail client, like Mozilla or Pine, is probably what you would prefer most of the time, but what about when you're on the road and you just want to check your e-mail from an Internet Cafe halfway around the world? Then a Web interface is really neat. All you need is a browser.

The prerequisites

Before you start, here's the shopping list:
  • The Apache Web server: apache_1.3.6.tar.gz
  • The IMAP server and libraries: imap-4.1.FINAL.tar.Z
    (Yes, I know the PHP documentation says you should get the latest version, but the latest didn't work with PHP for me so I reverted to one that had worked for me in the past).
  • PHP 3.0.7: php-3.0.7.tar.gz
You can do an exact search for these files on
http://ftpsearch.lycos.com/
to locate a copy near you.

Start by reading about the IMAP support in PHP. Compile the IMAP package and install the IMAP server and the libraries so PHP can link them when you build PHP. Then unpack the PHP source and read the file named INSTALL.DSO. This file should guide you through setting up PHP as a loadable Apache module.

When you have Apache with PHP3 and the IMAP libraries up and running, you can go ahead and install the Web mail interface and start playing with it.

How the code works

The code is pretty simple and straightforward. For simplicity it is divided into two parts: a library part, called
imapfuncs.phl
and the part that implements the main page and the general flow of things, called
index.php3
. The latter is the file you point your browser at after installing the code. To make Apache accept PHP files as directory indexes you can edit your
httpd.conf
so it contains the line:
   DirectoryIndex index.php3 index.html
When you install the code remember to
imapfuncs.phl
change these parameters to appropriate values:
    /* configurable parameters */

    $M_HOST        = "localhost";
    $M_MAILSERVER  = "transit.fast.no";
The first variable tells the Web mail interface where the IMAP server is running. The second line is used to tell the interface what domain name it should tuck onto the end of the username for outgoing mail.

Logging in

To limit access to the mailbox we use standard HTTP authentication, where the user logs in with her normal username and password on the system (make sure the user exists on the system and can access her mail through the IMAP server).

Logging in and opening the default mailbox for the user is done by calling the

m_login()
function defined in the
imapfuncs.phl
library file. This function checks to see if we've already logged in and whether we have given a username. If we're already logged in
m_login()
just returns and does nothing further.

The username is obtained from the built-in variable

$PHP_AUTH_USER
, which contains the username you typed in when you got the standard username/password dialog from your browser.

If the username is not set or the attempt to log onto the IMAP server failed

m_reject()
is called. This function sends a header back to the browser telling it that it needs a username and a password, or that the username and password supplied was wrong.

When the login is successful,

m_login()
stores the mailbox handle in a global variable for later use and then returns.




If you look at the argument list of

m_login()
you will see that we assign a value to the argument. This is a way of setting a default value for the argument so that if we call the function without that argument it is assigned a default value.

Also note that at the beginning of the function

m_login()
there are two lines beginning with the keyword "global" followed by a list of variables. Per default all variables used in the function are only valid within the scope of the function. To access global variables you have to declare them as such.

Next, if you look at where we call the

imap_open()
function you see that we prefixed the function name with a "@". This means that PHP should suppress error messages that may occur when calling this function.

Listing contents of a mailbox

After you have logged in the Web mail interface will show you a listing of your default mailbox and some buttons at the bottom of the browser window. On my machine this looks like this. For each message in your mailbox the Web mail interface shows you the sender, the subject, and the date it was sent.

To the left of every message there's a small checkbox. If you wish to delete several e-mail messages at a time you just check them and push the delete button.

The function

m_list()
in the file
imapfuncs.phl
is responsible for generating the listing.

Viewing a message

To view a message you click its subject in the mailbox listing. The Web mail interface will then call the function
m_display()
to show you the message. This may look something like this. The Web mail interface does very little processing before displaying a mail message so things might look a bit weird if you get a lot of multipart mail messages etc., but for educational purposes it'll do just fine.

Sending a message

There are basically two ways to send a message. You can either click the "compose" button on the mailbox listing page to create a new message, or you can click the "reply"-button on the message display page.

If you choose the latter you will get a message composition form with the recipient already filled in and the message you are replying to glued in and quoted in the text area where you type in your mail. However, if you choose the compose button on the mailbox listing page you get an empty form.

The function

m_compose()
is used to present both the empty mail form and the one that has been filled out as a reply to a mail message. The function checks to see if the optional arguments
$msgno
and
$mailbox
have been set. If they have been set it fetches the message the user is replying to and quotes it. Otherwise it just puts up a blank mail form.

Once the message has been composed the browser sends the contents of the mail form back to the webmail interface which then calls the function

m_send()
to actually send the message.

What can be made better?

A healthy dose of paranoia should tell most people that the solution has to be secured somehow. Especially if users are to access it from outside the corporate network. Probably the easiest way to improve security is to install an SSL-enabled Apache server so all the traffic between the user and the server is encrypted.

Most IMAP clients implement various methods to access, list, and manipulate mail folders on the server. It shouldn't be too hard to add this to our interface. Most of the code for listing mail folders and browsing messages in them is already there. (Notice how it makes a point of remembering what folder it was playing around in although the folder name is blank. The blank folder name is mapped to the default mailbox).

Handling attachments and multipart MIME messages isn't too hard to add either. Most of the functions you need to figure out the structure of such mail messages are already present in the IMAP library that PHP uses.

If your organization uses LDAP to keep track of information about its employees, organization, access privileges, and so forth, a natural extension of the Web mail interface would be to integrate it with LDAP. And of course, PHP can be built with support for LDAP.ø


Related resources

1. www.apache.org The Apache Web server project.
2. www.php.net Homepage for PHP3 info and development.
3. ftp://ftp.cac.washington.edu/imap/ University of Washington's IMAP directory
4. Some http://www.imap.org/ The basics on IMAP.
5. http://horde.org/imp/ IMP, a much more advanced IMAP interface written in PHP3.

Bjørn Borud is a research scientist in Norway at Fast Search and Transfer ASA, a company that develops large-scale search engines and image compression software. In his copious spare time, Bjørn reads, writes software, and contributes to various publications.



Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date