PHP: WonkyMail class for sending email.

Posted on January 10, 2012 by Jimmy K. in Projects, Tutorials.

This class has been four years in the making. It started as a very simple script when someone asked me to create a way to send email messages between users on their website. Over time, more features were added until it ultimately became what it is today. This class presently supports multiple file attachments, multiple recipients, and the ability to include custom headers.

In this article, I’ll give you a brief walkthrough of how to use this class as well as what each function does. Example and download links are at the bottom.

<?php

	class WonkyMail {
		
		/*
		 *
		 *   Class Name: WonkyMail
		 *   Author: Jimmy K.
		 *   Website: http://www.endseven.net/
		 *   Version: 1.0
		 *
		 *   I wrote this class for convenience when programming my projects. If you 
		 *   disagree with any of it's contents, don't use it. ;)
		 *
		 */
		
		var $aAttachments = array(); // store the attachments..
		var $aMessageHeaders = array(); // store the message headers..
		var $aRecipients = array(); // store the receipients..
		
		var $sMessageHTML = ""; // the html version of this message..
		var $sMessageTextOnly = ""; // the text-only version of this message..
		var $sSubject = ""; // the subject for this message..
		
		/* the constructor for this object. */
		public function __construct() {
			
			$this->sSubject = "Hello from WonkyMail!";
			$this->sMessageHTML = "This is a multi-part message in MIME format. It was sent using WonkyMail. &lt;<a href=\"http://cloud.endseven.net\" target=\"_blank\">http://cloud.endseven.net/</a>&gt;";
			$this->sMessageTextOnly = "This is a text-only message. It was sent using WonkyMail. <http://cloud.endseven.net/>";
			
			$this->jAddHeader("From", "Example <example@example.com>");
			$this->jAddHeader("Date", date("r"));
			
		}
		
		/* add a header. */
		public function jAddHeader($sKey, $sValue) {
			$this->aMessageHeaders[$sKey] = $sValue; // add the header..
		}
		
		/* remove a header. */
		public function jRemoveHeader($sKey) {
			
			if (array_key_exists($sKey, $this->aMessageHeaders)) {
				unset($this->aMessageHeaders[$sKey]); // remove the header..
			}
		
		}
		
		/* add a recipient. */
		public function jAddRecipient($sEmailAddress) {
			
			if (!array_search($sEmailAddress, $this->aRecipients)) {
				$this->aRecipients[] = strtolower($sEmailAddress); // add the email address
			}
		
		}
		
		/* remove a recipient. */
		public function jRemoveRecipient($sEmailAddress) {
			
			$iRecipientIndex = array_search(strtolower($sEmailAddress), $this->aRecipients);
			
			if ($iRecipientIndex !== false) {
				unset($this->aRecipients[$iRecipientIndex]); // remove the email address..
			}
		
		}
		
		/* add an attachment. */
		public function jAddAttachment($sPathToFilename) {
			
			$sFileContents = file_get_contents($sPathToFilename);
			$sFileContents = chunk_split(base64_encode($sFileContents));
			
			$this->aAttachments[$sPathToFilename] = array(basename($sPathToFilename), $sFileContents);
		
		}
		
		/* remove an attachment. */
		public function jRemoveAttachment($sPathToFilename) {
			
			if (array_key_exists($sPathToFilename, $this->aAttachments)) {
				unset($this->aAttachments[$sPathToFilename]); // remove the attachment..
			}
			
		}
		
		/* send the message. */
		public function jSendMessage() {
			
			list($sHeaders, $sMessage, $sRecipients) = array("", "", "");
			$sBoundaryName = "Boundary-" . date("U");
			
			// start the headers..
			$sHeaders .= "MIME-Version: 1.0\r\n";
			
			foreach ($this->aMessageHeaders as $oKey => $oValue) {
				$sHeaders .= $oKey . ": " . $oValue . "\r\n"; // add any custom message headers..
			}
			
			// don't delete this, pl0x..
			$sHeaders .= "X-Mailer: WonkyMail-1.0 by Jimmy K. <http://www.endseven.net>\r\n";
			
			// start the boundary..
			$sHeaders .= "Content-Type: " . (sizeof($this->aAttachments) > 0 ? "multipart/mixed" : "multipart/alternative") . "; boundary=" . $sBoundaryName . "\r\n\r\n";
			
			// text-only version..
			$sMessage .= $this->sMessageTextOnly . "\r\n\r\n";
			
			// text/html version..
			$sMessage .= "--" . $sBoundaryName . "\r\n";
			$sMessage .= "Content-Type: text/html; charset=iso-8859-1\r\n";
			$sMessage .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
			$sMessage .= $this->sMessageHTML . (sizeof($this->aAttachments) > 0 ? "<br /><br />" : "") . "\r\n\r\n";
			
			foreach ($this->aAttachments as $oKey => $oValue) {
				
				// attach each file..
				$sMessage .= "--" . $sBoundaryName . "\r\n";
				$sMessage .= "Content-Type: application/octet-stream; name=\"" . $oValue[0] . "\"\r\n";
				$sMessage .= "Content-Disposition: attachment\r\n";
				$sMessage .= "Content-Transfer-Encoding: base64\r\n\r\n";
				$sMessage .= $oValue[1] . "\r\n\r\n";
				
			}
			
			// close the boundary..
			$sMessage .= "--" . $sBoundaryName . "--\r\n";
			
			foreach ($this->aRecipients as $oKey => $oValue) {
				$sRecipients .= (!empty($sRecipients) ? ", " : "") . $oValue;
			}
			
			mail($sRecipients, $this->sSubject, $sMessage, $sHeaders) or die("Unable to send mail! :(");
		
		}
		
	}
	
	?>

How to create a WonkyMail message…

<?php

var $oWonkyMail = new WonkyMail();
$oWonkyMail->sSubject = "Hello from WonkyMail!";
$oWonkyMail->sMessageHTML = "This is an <strong>HTML</strong> message.";
$oWonkyMail->sMessageTextOnly = "This is plain text.";

?>

There you have it! Your WonkyMail message is created and we’ve applied a subject and text to it. Now we can do other neat things like add custom headers, attachments and recipients.

How to add and remove headers…

		/* add a header. */
		public function jAddHeader($sKey, $sValue) {
			$this->aMessageHeaders[$sKey] = $sValue; // add the header..
		}
		
		/* remove a header. */
		public function jRemoveHeader($sKey) {
			
			if (array_key_exists($sKey, $this->aMessageHeaders)) {
				unset($this->aMessageHeaders[$sKey]); // remove the header..
			}
		
		}

The functions jAddHeader() and jRemoveHeader() are used to add and remove headers, respectively. Headers are used to include useful (or sometimes required) information about the message such as: who the email is from, an optional reply address, an optional Campaign ID, etc.

An example of these functions would be:

$oWonkyMail->jAddHeader("From", "John Doe <john.doe@yourdomain.com>");
$oWonkyMail->jAddHeader("Reply-To", "John Doe <john.doe@yourdomain.com>");
$oWonkyMail->jAddHeader("X-Campaign-ID", "12345");
$oWonkyMail->jRemoveHeader("X-Campaign-ID");

How to add and remove recipients…

		/* add a recipient. */
		public function jAddRecipient($sEmailAddress) {
			
			if (!array_search($sEmailAddress, $this->aRecipients)) {
				$this->aRecipients[] = strtolower($sEmailAddress); // add the email address
			}
		
		}
		
		/* remove a recipient. */
		public function jRemoveRecipient($sEmailAddress) {
			
			$iRecipientIndex = array_search(strtolower($sEmailAddress), $this->aRecipients);
			
			if ($iRecipientIndex !== false) {
				unset($this->aRecipients[$iRecipientIndex]); // remove the email address..
			}
		
		}

The functions jAddRecipient() and jRemoveRecipient() are used to add and remove recipients, respectively. Recipients are the people that will receive your message in their inbox.

An example of these functions would be:

$oWonkyMail->jAddRecipient("john.doe@yourdomain.com");
$oWonkyMail->jAddRecipient("jane.doe@yourdomain.com");
$oWonkyMail->jRemoveRecipient("jane.doe@yourdomain.com");

How to add and remove attachments…

		/* add an attachment. */
		public function jAddAttachment($sPathToFilename) {
			
			$sFileContents = file_get_contents($sPathToFilename);
			$sFileContents = chunk_split(base64_encode($sFileContents));
			
			$this->aAttachments[$sPathToFilename] = array(basename($sPathToFilename), $sFileContents);
		
		}
		
		/* remove an attachment. */
		public function jRemoveAttachment($sPathToFilename) {
			
			if (array_key_exists($sPathToFilename, $this->aAttachments)) {
				unset($this->aAttachments[$sPathToFilename]); // remove the attachment..
			}
			
		}

The functions jAddAttachment() and jRemoveAttachment() are used to add and remove attachments, respectively. Attachments are files that are sent with your message that people can download to their computer, such as: expense reports; spreadsheets; and pictures of your cat, Fluffy.

An example of these functions would be:

$oWonkyMail->jAddAttachment("./files/Expense-Report-v1-24.pdf");
$oWonkyMail->jAddAttachment("./files/My-Cat-Fluffy-Is-So-Adorable.jpg");
$oWonkyMail->jAddAttachment("./files/Spreadsheet.xls");
$oWonkyMail->jRemoveAttachment("./files/Spreadsheet.xls");

How to send the message…

$oWonkyMail->jSendMessage();

Once you’ve created a message and added your recipient(s) and any custom headers or attachments, you are ready to send it. The function jSendMessage() will compile all the pieces together and send it out for you using the built-in PHP mail() function.

I like this class so much that I’ve used it with each website I create. I’ve also found this class to be stable enough to use in our internal email application, BHI Marketing Tools.

An example of this class can be found here.

You can download the latest version of this class in the END[SEVEN] Cloud.

 

Jimmy K. is a Chicago-based web developer who actively posts tutorials, articles and insights on his web development blog to help other programmers and developers.

You can find Jimmy on Google+ and Twitter.

 
 
 
 
 

If you like this, please leave a comment.

Name (required)
Email Address (required)
Website
Comments: