CK Cybers Time

Wednesday, May 9, 2007

PHP Mailer

PHPMailer is a PHP-Class for PHP (www.php.net) providing a package of functions to send emails. Main Features are HTML-Mail and Emails with attachments. For mailing, PHPMailer supports nearly all possiblities (old+ most of any ways) to send emails: mail(), sendmail, qmail & smtp-server directly. You can use any feature of smtp based emails: multiple to's, cc's, bcc's etc. In short: you can send emails with PHPMailer.

As you (might) know, you can already send mails with the php mail() function. So why do you need a class? Isn't it slower? - Yes that's true. But you don't pay a price if you won't get anything for it: PHPMailer makes it easy to send mails, gives you the ability of using attachments, sending HTML-messages and other stuff. With PHPMailer you can even use your own stmp-server and walk around sendmail routines used by the mail() function on *nix platforms.

This tutorial gives you the ability to implement the class into your script or website and helps you to build your own email application. If you just want to send simple mails and you have no problems with the mail() function I would suggest using it instead of the class, because it's part of the php-core and there is no need to implement PHPMailer.

First time

If you're young you might have been thought this will be about what you already know, but this is only about getting the class work right. Even if you have not used the php mail() function before, this paragraph will give you some information about email and emailing in general, too.
Before continuing be sure the class is installed correctly. If you feel uncertain, please read the installing instructions of the package. If you're still not sure, you can proof the correct install with this little script:

Save it as a php-file in the same directory your own script should. Call it and if you got no error, your installation had been done right. If you switched error messages and warnings off, then go ahead and set it on. Refer php manual about this.

This small piece of code is also the start of any use of PHPMailer. require("class.phpmailer.php"); includes the sourcecode of the class (even the function is called require, let's say includes) and $mail = new PHPMailer(); instances the class to $mail. It means, you can access all features, functions and methods of the class via the variable (object) $mail.

To instance a class is quite useless and boring. Let's go ahead and send out the first mail. For this you have to remember what you need: An address where the mail is send to, one where it's from, a subject and the text of the mail, called mail-body or only body in short. I think you have all this stuff already in mind.
What we need, too, is the method how you want to send the mail off. Wondering about this ? We need a program to communicate with an smtp server which indeed sends the mail out into the internet. That's what I mean when I say 'method'. In the *nix world, sendmail is very popular and used widely. For mail in general, remember your mail client settings, you use an smtp server.

With PHPMailer, different methods to send a mail out are possible. For now I suggest SMTP, as mentioned above mail() function, sendmail or qmail is possible either. For SMTP, you need a valid smtp server. This, for example, is your working one from your mail client. Working one means, the from email address should be accepted by the smtp server. If not, sending the mail out will fail.
Now, all stuff needed for the first mail is in order and that's how it works:

IsSMTP(); // telling the class to use SMTP
$mail->Host = "smtp.email.com"; // SMTP server
$mail->From = "from@email.com";
$mail->AddAddress("myfriend@site.com");

$mail->Subject = "first mailing";
$mail->Body = "hi ! \n\n this is First mailing I made myself with PHPMailer !";
$mail->WordWrap = 50;

if(!$mail->Send())
{
echo "Message was not sent";
echo "Mailer Error: " . $mail->ErrorInfo;
}
else
{
echo "Message has been sent";
}
?>

Make it a php file and change the values to your needs. For this, here is a list from top to bottom what this script does:
$mail->IsSMTP();

This sets up STMP-Server as method to send out email(s).
$mail->Host = "smtp.email.com";

Setting smtp.email.com as smtp server. Just replace it with your own SMTP-Server address. By the way, you can even specify more then one, just seperate them with a semicolon (;): "smtp.email.com;smtp2.email.com". If the first one fails, the second will be taken. This makes sense, if you know the mail server is sometimes down. I mean, Open Source made a lot of stuff reliable, but sometimes things even fail with Open Source.

Just put in the address from where the email should be send from. You can take any address which is valid for the SMTP-Server. The person who will get the mail then knows who had sent the mail.
$mail->From = "from@email.com";

If a mail address is too puritan for you, you can add another line of code to give the address a name. This will add 'Your Name' to the from-address, so people now know, who had sent the mail.
The following line
$mail->FromName = "Your Name";

The following will add the to-address and that's the address where the email is send to. Take a valid email here, too, so that you can proof that your mailing worked. My suggestion is: take your own address, too, or the one of your friend next to you, so she or he can check mails for you. You can add also (like from), a name to the email. This is done in a different way, check out this piece here:
$mail->AddAddress("myfriend@site.com","Friends name");
$mail->AddAddress("myfriend@site.com");

The next part is again very simple. Setting the subject and body is done there. $mail->WordWrap = 50; is a feature of PHPMailer to wordwrap your message automatically. This means, all lines will be in a maximum length of characters, even if not set as body= .... In my code here, it makes really no sense, but, hey, this is one of the nice functions provided by the class.

And again a simple part. Sending out the mail with all settings required is done with $return = $mail->Send();. In this small script, it's combined with an error message. If Send() fails, it'll return false and you can catch it and display an error message. This is done in the last lines. Or in case of success, it displays a kind of 'done' message. Hope your script works, if not, check out all syntax and logic errors.

Using attachments

Get the bunch out. Sending simple mails will get boring, what you maybe want is to attach something to your mail, let's say a photo of your dog or any file you ever want to be send via email. PHPMailer is able to handle that. And the way is easy. Probably you want to send even more than a file in one mail, no problem at all, there are no limitations given. But think about it: The bigger your attachment is, the bigger the mail will be (every file will blow up about 30% bigger in size even).
But don't hesitate. There are two ways of attaching something to your mail: First, you can simply attach a file from the filesystem (remote won't work) and Second, you can attach (binary) data stored in a String variable. It's called Stringattachment. This enables you to put data out of a database and attach it to your email.

File Attachments

Let's start coding. In your code, a new command to attach a file can be placed anywhere between $mail = new PHPMailer(); and !$mail->Send(); and it's called AddAttachment($path);. And that's it. This single line will add the Attachment to your mail. But what's about the parameter for this command. Easy again:

$path is the path of the filename. It can be a relative one (from your script, not the PHPMailer class) or a full path to the file you want to attach.

If you want more options or you want to specify encoding and mime/type of the file, then you can use three more parameters which are all optional:
AddAttachment($path,$name,$encoding,$type);

$name is an optional parameter for you to set the filename which will occur in the mail you'll send out. The person who will recieve your mail will then only see this name instead of the original filename.

$encoding is a little more technical, with this parameter you can set the type of encoding of the attachment. Default is base64. Other types that are supported are: 7bit, 8bit, binary & quoted-printable. Please refer to your smtp documentation about encoding and the differences between types. In general, mailservers will convert encodings they don't want to handle into their preferred encoding type.

$type is the mime-type of your attached file. In internet you don't specify the filetype with an ending dot and suffix, a so called mime-type (MIME = Multipurpose Internet Mail Extensions) is used. This parameter gives you the possibility to change it from the default value of application/octet-stream (which works with every kind of file) to a more specific mime type like image/jpeg for a .jpg-photo for example.

String Attachments

Stringattachments have been supported since PHPMailer version 1.29. This method works quite like AddAttachment() and is called AddStringAttachment($string,$filename,$encoding,$type). Naturaly you have to pass your string data to the method and that's the first parameter $string. Because the string will lead into a standard file (that's what an attachment will be if you receive it via mail), the $filename parameter is not optional now. Use it to give your data a filename.

The rest is just the same as described in detail above.

So, why should AddStringAttachment be used instead of AddAttachment? Is it for Text-Only files? - No, not at all. It's for Databases for example. Data stored in a Database is always stored as a string (often called blob). You can for example query your database and pass the returned string to the AddStringAttachment. Therefore you use it.

Inline Attachments

There is an additional way to add an attachment. If you want to make a HTML-message with Images, you have to make an attachment of the image and then link the CID" /> tag to it. This is done with a so called CID. For example, you add an image as Inline Attachment with the CID my-photo, you access it within the HTML-mail Part with <img src="cid:my-photo" alt="my photo" />. It's that easy!

Here is the function to add the Inline Attachment in detail:

$mail->AddEmbeddedImage(filename, cid, name));
By using this function with this example's value above, leads into this code:
$mail->AddEmbeddedImage('my-photo.jpg', 'my-photo', 'my-photo.jpg '));

For more Information about HTML-Mails, see the Chapter Using HTML Mail.

Handling Attachments

If you want to attach multiple files (or strings), just call AddAttachment() or AddStringAttachment() multiple times. If you want to remove an attachment, you can't specify a single one, but you can remove all attachments from your mail by calling ClearAttachments(). This will remove all Attachments, this means all File-, String-, and Inline-attachments.

Using HTML Mail

Anyone with little art in mind likes to design the mail he or she sends out. For this you can use HTML formattings in your mail. If you're not familiar with HTML, please consult a tutorial or manual about it.

But sending out HTML-Messages depends not only on your knowledge in HTML, it also depends on the receiving person's email client, which should be compatible with these HTML-mails. For those mailclients which are not able to display HTML formattings, you can use an alternative (old+ alternate ??) body containing your message as plain text.

Let's take a look what to do. First we'll simply create a basic HTML message:

IsSMTP(); // telling the class to use SMTP
$mail->Host = "smtp.email.com"; // SMTP server

$mail->From = "from@email.com";
$mail->AddAddress("myfriend@site.com");

$mail->Subject = "look, it's a HTML message";
$mail->Body = "hi my friend! \n\n this message uses html entities !";

?>

It's just as easy as making a normal mail. You just take a string with HTML formattings as $mail->body.
Before sending this out, we have to tell the PHPMailer object, that we want to use a HTML message. In detail this means, the body has to be setup as multipart/alternative. The is done with:

$mail->IsHTML(true);

To make the HTML-message perfect then, you can use $mail->AltBody="hi my friend! \n\n this message uses html entities, but you prefer plain text !"; to set the alternative (old+ alternate ??) body (AltBody in short). If you use this feature, the mail will be automatically set as multipart/alternative and you do not need to use $mail->IsHTML(true); any more.

That's the way you can send out HTML-messages. Just apply the send-command after it and the mail is out. I myself would not recommend using HTML messages, because these messages are often used for viruses and exploits, they are bigger than simple plain-text mails and are not standarized in the way the plain-text mail is. On the other hand, even attachments are used for viruses, but nobody would stop sending mails with attachments. It's just your decision and PHPMailer is able to be a solution for both, Emails with HTML or without.

If you want to send out a HTML-message with pictures, or even flash animations or whatever, PHPMailer supports this as well. Adding a picture to your HTML-message for example is explained in the Chapter Inline Attachments in detail and should lead you to your 'I am a superb HTML-Message-Designer' pleasure. For short, here are 2 lines of Code you've to insert before sending the mail out:

$mail->AddEmbeddedImage("rocks.png", "my-attach", "rocks.png"));
$mail->Body = 'Embedded Image: PHPMailer Here is an image!';