Most people can write basic scripts that send emails using the php mail command. This presentation will show you how to be a little more adventureous with your emails by sending html formatted, embedding images and providing attachments with your outgoing emails. We will also look at how to read emails, and set up a mail server as well.
If you already have web-hosting then generally you are using their mail server or your ISP for sending emails. But... you wouldn't tell someone that they had to get web-hosting to learn PHP. Similarly you don't need web-hosting or ISP to start sending emails (to yourself on your local machine).
Apologies to the Linux people here, but I can't help you with your mail server. For the windows people I use Mercury Mail or hMailServer, both of which are freely available for download. I also use Pegasus Mail (from the mercury download), thunderbird and outlook express as my email clients.
If I remember correctly, setting up Mercury Mail is painless, and requires the following:
The following screen shots illustrate the concept better.
Setting up hMailServer looks like it should be simple, and it probably would be if I wasn't concerned with virtual hosts and a box not connected to the internet.
But despite my sterling efforts, I still haven't quite figured it out yet!
The following screen shots show some of the hMailServer interface.
Certainly you can use the mail command for simple emails, but for complicated stuff I use htmlMimeMail5. It allows me to do all the cool stuff (like adding attachments, embedding images etc), and it is very easy to use. I kid you not! Infact the hardest part about using this library is trying to find where to download it from.
The website provides 2 download options. The htmlMimeMail-2-5-2.zip file is for PHP4, whereas htmlMimeMail5.zip is the PHP5 version.
require_once('htmlMimeMail5.php');
//--create a new mail object.
$mail = new htmlMimeMail5();
$mail->setFrom('Brent Knigge <nospam@nospam.com>');
$mail->setSubject('Test email');
$mail->setPriority('high');
$mail->setText('Sample text');
$mail->setHTML('<b>Sample HTML</b>');
$mail->addEmbeddedImage(new fileEmbeddedImage('background.gif'));
$mail->addAttachment(new fileAttachment('example.zip'));
$mail->send(array('to_someone@acu.edu.au', 'another_person@acu.edu.au'));
unset($mail);
The example on the previous slide is about the extent of the functions that I use with htmlMimeMail5. It does all the fancy things that I've ever needed to do, and should be adequate for a majority of cases.
Consider this code
$mail = new htmlMimeMail5();
$mail->setFrom('Brent Knigge <nospam@nospam.com>');
$mail->setSubject('Test email');
foreach($email_array as $object)
{
$mail->setText($object->letter);
$mail->send(array($object->email_address));
}
unset($mail);
ALL the code must be contained within the foreach loop. This is because once some of the properties have been set, they are permanently set! In the previous example we will send out emails to the recipients, BUT the email text will always be the text that was set for the first email. This is obviously not good if your email body differs for each recipient.
The IMAP extension incorporates the IMAP protocol for emails. This extension allows you to send and receive emails, although libraries like htmlMimeMail will build emails for you. I have found libraries that supposedly read emails to be pretty crappy or just not work at all.
Inorder for the examples to work, you will need the IMAP extension (PECL package) with your PHP installation
Before we jump in and start using IMAP it's important to understand the fundamentals. Just like database programming in PHP; You connect to a server, select the database, execute your query, do something with the result set (if any), then optionally free your resources.
IMAP is similar in that you
Let's send an email
<?php
$mbox = imap_open("{localhost:110/pop3}INBOX", 'brent', 'brent');
echo imap_body($mbox, 1, FT_PEEK);
imap_close($mbox);
?>
Unfortunately the FT_PEEK didn't seem to work for me because once I had read the message, it disappeared from the server.
<?php
$mbox = imap_open("{localhost:110/pop3}INBOX", 'brent', 'brent');
$headers = imap_headers($mbox);
foreach($headers as $key => $value)
echo "KEY: $key VALUE: $value <br />";
imap_close($mbox);
?>
imap_headerinfo is a nice function that doesn't mess anything up with the email or the server (i.e. it doesn't remove it from the server or set the read flags).
<?php
$mbox = imap_open("{localhost:110/pop3}INBOX", 'brent', 'brent');
$headers = imap_headerinfo($mbox, 1);
foreach($headers as $key => $value)
echo "KEY: $key VALUE: $value <br />";
imap_close($mbox);
?>
<?php
$mbox = imap_open("{localhost:110/pop3}INBOX", 'brent', 'brent');
$headers = imap_headerinfo($mbox, 1);
echo '<br />$headers->sender[0]->personal:' . $headers->sender[0]->personal;
echo '<br />$headers->sender[0]->mailbox:' . $headers->sender[0]->mailbox;
echo '<br />$headers->sender[0]->host:' . $headers->sender[0]->host;
imap_close($mbox);
?>
<?php
$mbox = imap_open("{localhost:110/pop3}INBOX", 'brent', 'brent');
$header = imap_headerinfo($mbox, 1, 80, 80);
$subject = $header->fetchsubject;
$date = date('YmdHis', $header->udate);
$text = imap_body($mbox,1);
echo '<br />subject: ' . $subject;
echo '<br />date: ' . $date;
echo '<br />body: ' . $text;
imap_close($mbox);
?>
Output is shown on the next slide
The output from the previous code

There are other IMAP functions that I use, and they are listed below so that you can explore these further
Some functions that don't seem to do what I think they're supposed to do are imap_list, imap_listmailbox. For some reason I can't get them to work on the localhost
If you call imap_open and the mailbox you are connecting to has no messages, then you will get a 'Mailbox is empty' notice. So you end up having to write code like this:
//--hide the imap notice from users
error_reporting(E_ALL & ~E_NOTICE);
$mbox = imap_open("{127.0.0.1:110/pop3}INBOX", "brent", "brent");
if(imap_last_error() == 'Mailbox is empty' )
return;
...
When looping through the emails, the message_id attached to each email is dynamic. Thus if we started at the first email (id 1), and read it, then it drops off the list. The second email on the list becomes number 1 and so on. This is why my loop starts at the highest and works it way down.
...
$num_msg = imap_num_msg($mbox);
for($i = $num_msg; $i > 0; $i--)
{
$header = imap_headerinfo($mbox, $i, 80, 80);
$subject = $header->fetchsubject;
$date = date('YmdHis', $header->udate);
$text=imap_body($mbox, $i);
}
I am developing a class that makes reading emails much easier. It can also handle attachments, html email etc. Here is a sneak peek
$emailObject = new TEmail($mbox, $i); //--can be email, host or personal echo "\n" . $emailObject->sender['email']; echo "\n" . $emailObject->from['personal']; //--can be plain or html echo "\n" . $emailObject->emailbody['plain']; echo "\n" . $emailObject->subject; echo "\n" . $emailObject->date;