Login

A MIME Mailer Class

Setting up a web application to send plain text email is easy. What if you need the email to handle other content, such as images or special document formats? This article explains how to design a PHP class for sending email with attachments.

Email has become an important part of life these days. More and more web applications are expected to be capable of using email to communicate. Online stores in particular need a way of confirming orders, sending gifts certificates and distributing information about specials among other things. You may want to send an HTML formatted greeting to the registered visitors of your blog, publish a newsletter in an automated fashion or even code a custom email application for your own use on a personal web server. You may even want to provide basic web email services to users of a small web community.

Sending plain text email is pretty easy in most web application environments. Within a PHP application you can use the “mail()” function. Where things get more interesting is when your requirements extend to other content such as images, HTML, PDF, RTF, CSV or other document formats

This article outlines the design of a PHP class for sending email with attachments. Everything you need to do this is supplied by the core PHP system, so nothing additional (such as non-bundled extensions) should be needed save for the required set up and connection between PHP and a SMTP mail package such as Sendmail or Postfix. For details on setting up Sendmail and PHP, read through the appropriate section of the PHP manual. If you are already using the mail() function in PHP, you are ready to go right now.

The Benefits of the Design

Of late I have had my fill of code written with a single application and purpose in mind. The kind of code I mean is long procedural code, hardcoded with names and string values specific to that project, and almost always spread out over multiple documents. Want to modify it? Good luck! Want to use it somewhere else? Yeah right! Many times it might seem quicker to write something in this way, but when it comes time to alter it in any way you’ve got a problem. If you didn’t write it in the first place, it makes it that much worse.

This class was designed based on the functionality of some code written in that very way. Rather than labor for hours trying to modify this code I decided to encapsulate the operation in a class. What I ended up with is a piece of code that can be used in any project and never has to be written again. For those that haven’t used classes, coding in this manner allows you to assemble larger applications out of smaller widgets. How simple or complex in function you make your classes are up to you, but you may find that keeping it simple is the best approach. The PHP language may not have all of the features of a completely object oriented language such as Java or C# but what it does have can save you hours of frustration if you let it.

The mime_mailer class has three methods (including the constructor) that can be considered “public” and is all you need to reliably send email with attachments from a PHP application. You could easily extend this class with other classes that produce files of various types, provide shopping, checkout and payment services, process input from forms, work with the local file system and a long list of other useful functions.

{mospagebreak title=You’ve Got Mail}

The first order of business is to initialize some variables and provide a constructor for the class.

Some of these are pretty self explanatory. It’s easy to see who the email is from, who it goes to, the subject and the body of the message. Other variables are provided for headers, an array is for file contents and two boolean values are intended as checks to determine that we have everything before sending the mail. It might be useful in some situations to employ email address validation before sending to help ensure that nothing goes wrong. Next is the constructor method.

As long as all the necessary values are valid, several variables are set with the constructor. In addition the “set_body()” method is called in order to place the body of the message inside the proper mime content. The “MIME_BOUNDRY” marks individual sections of the mail. Use two line returns before and after each content block (this goes for the attachment content as well).

The “add_attachment()” method is pretty simple. It accepts the string path to a file to attach as an argument. It calls the “set_file_section()” method which loads the file, encodes it and places it in the proper mime content. In order to insert the proper mime type for the file into the string, we need to send the file name to a function that determines the mime type based on the file extension. There are a lot of these functions available on various sites and more complex classes that use the mime types file that is used by Apache.

For this class I have written a basic mime type function that supports the formats I most commonly encounter in my work. If you have additional ones that you wish to support, adding mime types to this function is as simple as adding to the switch construct.

The final two methods send the mail. If the proper headers and body information is set, the mail message is assembled from all the information previously gathered. The “assemble()” method is called to assemble the attachment data and put it together with the body of the message.

Formatting can be important to the success of the mailing. Attachments can fail to appear or be corrupted if the output is not correct. If you have any trouble while modifying or adding to this class, consult documentation about mime formatting to determine what might have gone wrong.

The Code in Use

Using the mime_mailer class is a simple matter. The first line you will need is to include the file in your application. You then initialize an instance of the class, add your attachments and send the mail. Use as many instances as you need. The to, from, subject and body information can come from any source in your application you need it to.

There are quite a few applications where this basic functionality would be indispensable. Wrapping it all up into just a few lines can save a lot of time and effort. Experiment with the code, use it in your applications, and if you have any modifications that you think will be useful to others, please share them, and please email responsibly.