A Simple Mail Object

Sending plain emails with PHP can be pretty easy. On a basic level you can just call mail(), which triggers the server-side sendmail command. Pass in three parameters (a recipient email address, subject, and message) and you're done. When you start looking into file attachments and HTML messages, though, things start to get a bit more complicated.

PHP's mail() function allows a fourth parameter to be passed to declare headers. E-mail clients will need a bit of help figuring out if a message is plaintext, HTML, or something much more complicated. If you don't pass in any headers they (usually) default to plaintext. This fourth parameter is not the only way to add context to the email; the message can declare headers in between breaks to differentiate between content types. I recently had a battle with this, specifically regarding Outlook's interpretation of these headers and breaks, and decided to sit down and write a nice wrapper for my MVC to handle various message types.

Since I was working within an object-orientated codebase I had a few obvious specifications in mind. First, all of this functionality should exist within a class setup that I could call easily from anywhere in my codebase. After battling with the syntax for attachments I wanted the code to be able to handle several use cases (with and without plaintext, HTML, and attachments). Adding extra recipients to an email should be easy and not require separate mail instances to be spun up. Finally, as I've learned the hard way, I'll want to change up this class in the future, so I tried to break up pieces that I'll want to change in the future to avoid total rewrites. This is the class I came up with: Archangel PHP Mailer.

There are a few pieces that I don't like about the first build. The initial Mail::get_message() method is horrifically long. I spent some time trying to slim it down and break it into separate methods, but with seven different possible combinations of message/header it was difficult to do it elegantly. Mail::get_additional_headers() suffers from that same problem, though not as bad. In retrospect it may be worth it to create several separate classes to either abstract out some of this functionality or completely sandbox it, just not sure if the small increase in readability would be worth the extra files.

The first thing I'd like to tackle, though, is the validation. While requiring at least one recipient, a subject, and one message type is enough to get things rolling, it'd be nice to validate that the attachment is valid, the fields are formatted to the correct RFC standard, and that every email with HTML has a plaintext fallback. The code itself could be cleaned up next, especially the message formation area.

Of course, adding some extra functionality would be nice. Adding CC and BCC is something that my current (and more simple) mail logic already does. Multiple attachments could prove useful in some cases. Simplifying Mail::setAttachment() wouldn't be too difficult (as long as your server can detect mime types, that is). For now this class has been tested and can be used, but I plan on tinkering around with it a little bit in the future.

Note: there are some really cool existing mail wrappers out there for PHP, including PHPMailer and Swiftmailer. I build this one from scratch simply because I wanted to dive into some of the intricacies and understand how mail works a bit more. By no means do I think that Archangel is superior to the options that have been developed and tested for years. Besides, it was fun :)