Easy to use, yet powerful PHP E-mail Class

July 21, 2009 by Jeff Gibeau Leave a reply »

This is a pretty robust PHP Email class that I wrote a few years back. Has the capability to do text or html e-mails with multiple attachments. Enjoy!

<?php
/******************************************************************************\
--
--	Class Name: eMail
--		Purpose: Handles various aspects of sending/generating e-mails in PHP.
--		Current Capabilities:
			- Allows multiple "To" recipients
			- Allows multiple "Cc" recipients
			- Allows multiple "Bcc" recipients
			- Allows "From" header to be modified
			- Allows "Sender" header to be modified
			- Allows "Content-Type" for text or html
			- Allows for multiple attachments
			- Checks e-mail addresses via regular expressions to verify they
				will not cause errors
			-
--
\******************************************************************************/


	//Define class
class eMail {

/******************************************************************************\
--
--	User Specific Variables
--		Purpose: Variables which should/may be modified by the user.  This
--			defines defaults used in the program that can be changed later.
--
\******************************************************************************/
	//Set Default Variables
	var $replyTo = 'System <system@example.com>';	//Default reply address
	var $from = 'System <system@example.com>';		//Default From address
	var $sender = 'System <system@example.com>';	//Default Sender address
	var $isHTML = false;				//False sends e-mail in plain text by default
	var $nl = "\n";						// New Line character, either \r\n or \n


/******************************************************************************\
--
--	Constant variables
--		Purpose: The constant variables should not be changed/modified unless
--			you know what you are messing with.
--
\******************************************************************************/
	//Constants
	var $errors = null;				//Array to hold any errors which may occur
	var $attachments = null;		//Array to hold attachments
 	var $mime_boundary = null;		//boundary set for using attachments
	var $to = null;					//Array to hold recipients
	var $cc = null;					//Array to hold recipients
	var $bcc = null;				//Array to hold recipients
	var $header = null;				//Header used to send e-mail
	var $subject = null;			//Subject of the e-mail
	var $body = null;				//Message portion of the e-mail
	var $message = null;			//used to build message when mail is sent


/******************************************************************************\
--
--	Regular Expressions
--		Purpose: Used in error checking e-mail addresses and various parts of
--			the emails.
--
\******************************************************************************/

 	//Regular Expressions for Error Checking
		//Email address with no name attached
	var $regex_email = '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+$';
		//Email address with name attached
	var $regex_email2 = '^([\._A-Za-z0-9-]+[ ]+)+[<][_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+[>]$';
 		//Regular Expression for limiting body of message
 	var $regex_body = '^.*$';
 		//Regular Expression for limiting subject of message
 	var $regex_subject = '^.+$';


/******************************************************************************\
--
--	User Functions
--		Purpose: Allows user to add recipients, attachments, body, subject,etc.
--
\******************************************************************************/

		//Class Constructor, automatically called when a new object is created
	function eMail(){}

		//Adds a recipient for the e-mail
	function addTo($email_addr){
		$email_addr = $this->clean_email($email_addr);
		if($this->verify_email($email_addr)){
			$this->to[sizeOf($this->to)] = $email_addr;
			return true;
		} else{
			return false;
		}
	}

		//Adds a Carbon Copy address for the e-mail
	function addCC($email_addr){
		$email_addr = $this->clean_email($email_addr);
		if($this->verify_email($email_addr)){
			$this->cc[sizeOf($this->cc)] = $email_addr;
			return true;
		} else{
			return false;
		}
	}

		//Adds a Blind Carbon Copy address for the e-mail
	function addBCC($email_addr){
		$email_addr = $this->clean_email($email_addr);
		if($this->verify_email($email_addr)){
			$this->bcc[sizeOf($this->bcc)] = $email_addr;
			return true;
		} else{
			return false;
		}
	}

		//Sets the from header for the e-mail
	function setFrom($email_addr){
		$email_addr = $this->clean_email($email_addr);
		if($this->verify_email($email_addr)){
			$this->from = $email_addr;
			return true;
		} else{
			$this->addError("Invalid Format for FROM e-mail address");
			return false;
		}
	}

		//Sets the ReplyTo header for the e-mail
	function setReplyTo($email_addr){
		$email_addr = $this->clean_email($email_addr);
		if($this->verify_email($email_addr)){
			$this->replyTo = $email_addr;
			return true;
		} else{
			$this->addError("Invalid Format for ReplyTo e-mail address");
			return false;
		}
	}

		//Sets the Sender header for the e-mail
	function setSender($email_addr){
		$email_addr = $this->clean_email($email_addr);
		if($this->verify_email($email_addr)){
			$this->replyTo = $email_addr;
			return true;
		} else{
			$this->addError("Invalid Format for Sender e-mail address");
			return false;
		}
	}

		//Sets the From, ReplyTo, and Sender header with one e-mail
	function setSenderInfo($email_addr){
		$email_addr = $this->clean_email($email_addr);
		if($this->verify_email($email_addr)){
			$this->replyTo = $email_addr;
			$this->sender = $email_addr;
			$this->from = $email_addr;
			return true;
		} else{
			$this->addError("Invalid Format for From, Sender, and ReplyTo e-mail addresses");
			return false;
		}
	}

		//Sets the subject of the e-mail and verifies that all characters are allowed
	function setSubject($subjectIn){
		if($this->verify_subject($subjectIn)){
			$this->subject = $subjectIn;
			return true;
		} else{
			return false;
		}
	}

		//Sets the body of the e-mail and verifies that all characters in the body is allowed
	function setBody($bodyIn, $html_flag = false){
		$this->isHTML = $html_flag;
		if($this->verify_body($bodyIn)){
			$this->body = $bodyIn;
			return true;
		} else{
			return false;
		}
	}

		//Adds an attachment to be sent with the email
	function addAttachment($fileData, $fileName = "unknown", $fileType = ""){
		$currSize = sizeOf($this->attachments);
		$this->attachments[$currSize][0] = $fileData;
		$this->attachments[$currSize][1] = $fileName;
		$this->attachments[$currSize][2] = $fileType;
	}



/******************************************************************************\
--
--	Send Mail Function
--		Purpose: Sends the e-mail after everything is setup.
--
\******************************************************************************/
		//Sets the mail headers for HTML, generates all the e-mail parameters and sends it
	function sendMail(){
			//Check body content via regular expression
		$this->verify_body($this->body);
			//Check subject content via regular expression
		$this->verify_subject($this->subject);

			//Verify at least on "To","Cc", or "Bcc" address is contained
		if($this->to==null && $this->cc==null && $this->bcc==null){
			$this->addError("E-mail must contain at least one \"To\",\"Cc\", or \"Bcc\" address");
		}

			//Begin to build the header
		$this->header = "";
			//Set a MIME-version
		$this->header .= "MIME-version: 1.0" . $this->nl;

			//Setup Sender, From, Bcc, CC, and ReplyTo regardless of mail format
		$this->replyTo = $this->clean_email($this->replyTo);
		if($this->replyTo != null){
			if($this->verify_email($this->replyTo)){
				$this->header .= "Reply-To: $this->replyTo" . $this->nl;
			} else{
				$this->addError("Invalid Reply-To Header: $this->replyTo");
			}
		}

			//Setup sender
		$this->sender = $this->clean_email($this->sender);
		if($this->sender != null){
			if($this->verify_email($this->sender)){
				$this->header .= "Sender: $this->sender" . $this->nl;
			} else{
				$this->addError("Invalid Sender Header: $this->sender");
			}
		}

			//Setup from
		$this->from = $this->clean_email($this->from);
		if($this->from != null){
			if($this->verify_email($this->from)){
				$this->header .= "From: $this->from" . $this->nl;
			} else{
				$this->addError("Invalid From Header: $this->from");
			}
		}

			//Verify all addresses in cc
		if($this->cc!=null){
			foreach($this->cc as $email_addr){
				$email_addr = $this->clean_email($email_addr);
				$this->verify_email($email_addr);
				$email_addr = $email_addr;
				$this->header .= "Cc: $email_addr" . $this->nl;
			}
		}

			//Verify all addresses in bcc
		if($this->bcc != null){
			foreach($this->bcc as $email_addr){
				$email_addr = $this->clean_email($email_addr);
				$this->verify_email($email_addr);
				$email_addr = $email_addr;
				$this->header .= "Bcc: $email_addr" . $this->nl;
			}
		}
			//If contains attachments, generate mail with multiple parts
		if($this->attachments!=null){
				//Generate a boundary to separate the message body
				//  and attachments
			$this->mime_boundary = "==Multipart_Boundary_x{".md5(time())."}x";

				//Set Content type to multipart for attachments
			$this->header .= "Content-type: multipart/mixed;" . $this->nl;
				//Put boundary in header of e-mail
			$this->header .= " boundary=\"{$this->mime_boundary}\"";

				//Setup the boundary for the body content
            $this->message .= "--{$this->mime_boundary}" . $this->nl;

				//If html set content type to that in message, else plain text
			if($this->isHTML){
	            $this->message .= "Content-Type: text/html; charset=ISO-8859-1" . $this->nl;
			} else{
				$this->message .= "Content-type: text/plain; charset=ISO-8859-1" . $this->nl;
			}
				//Set transfer encoding
			$this->message .= "Content-Transfer-Encoding: 7bit" . $this->nl . $this->nl;

				//Add the body to the message
			$this->message .= $this->body . $this->nl . $this->nl;

				//Add attachments
			for($i=0;$i<sizeOf($this->attachments);$i++){
					//Put boundary before each attachment
				$this->message .= "--{$this->mime_boundary}" . $this->nl;
					//Set content type of attachment
				$this->message .= "Content-Type: {$this->attachments[$i][2]};" . $this->nl;
					//Set name for the attachment
				$this->message .= " name=\"".$this->attachments[$i][1]."\"" . $this->nl;
					//Let message know this is an attachment
				$this->message .= "Content-Disposition: attachment;" . $this->nl;
					//Set filename for the attachment
				$this->message .= " filename=\"".$this->attachments[$i][1]."\"" . $this->nl;
					//Set to base64 content encoding
				$this->message .= "Content-Transfer-Encoding: base64" . $this->nl . $this->nl;
					//Add attachment and encode to base64
				$this->message .= chunk_split(base64_encode($this->attachments[$i][0])) . $this->nl;
			}
				//Close off attachments
			$this->message .= "--{$this->mime_boundary}--" . $this->nl . $this->nl;
		}
			//Does not contain attachments, generate mail normally
		else {
				//If html set header to define it
			if($this->isHTML){
				$this->header .= "Content-type: text/html; charset=iso-8859-1" . $this->nl;
			} else{
				$this->header .= "Content-type: text/plain; charset=ISO-8859-1" . $this->nl;
			}
				//Add body to the message
			$this->message = $this->body;
		}

			//Generate To: recipients
			$to_string = "";
		if($this->to!=null){
			$this->count=0;
			foreach($this->to as $email_addr){
				$email_addr = $this->clean_email($email_addr);
				if($this->verify_email($email_addr)){
					if($this->count>0){
						$to_string .= ', ';
					}
					$to_string .= $email_addr;
					$this->count++;
				}
			}
		}
			//If an error has occurred, do not send the message and return the last error
		if($this->errors!=null){
			return false;
		} else{
				//Close off the header of the message
			$this->header .= $this->nl;
				//Send the message
			return mail($to_string, $this->subject, $this->message, $this->header);
		}
	}

/******************************************************************************\
--
--	Error Functions
--		Purpose: Internal functions to store errors and public ones to retrieve
--			them.
--
\******************************************************************************/
		//Returns the array of errors
	function getErrors(){
		return $this->errors;
	}

		//Returns only the last error which was logged
	function getLastError(){
		if($this->errors!=null){
			return $this->errors[sizeOf($this->errors)-1];
		} else {
			return false;
		}
	}

		//Adds an error to the error array
	function addError($errorIn){
		$this->errors[sizeOf($this->errors)] = $errorIn;
	}

/******************************************************************************\
--
--	Message Compilation Functions
--		Purpose: Functions which return different components of the message
--
\******************************************************************************/
		//Returns the message header
	function getHeader(){
		return $this->header;
	}

		//Returns the message contents, not generated until after mail is sent
	function getMessage(){
		return $this->message;
	}

		//Returns the body portion of the e-mail
	function getBody(){
		return $this->body;
	}

/******************************************************************************\
--
--	Error Checking/Cleansing Functions
--		Purpose: Functions to remove common errors from input and to verify
--			different portions of the message with regular expressions
--
\******************************************************************************/
		//Removes e-mail addresses of commas and semi-colons which may cause
		// problems in the message headers
	function clean_email($email_addr){
		if($email_addr!=null){
			$email_addr = str_replace(","," ",$email_addr);
			$email_addr = str_replace(";"," ",$email_addr);
		}
		return $email_addr;
	}

		//Verifies that e-mail addresses in arguments match one form of
		// e-mail via regular expressions
	function verify_email($email_addr){
		if (eregi($this->regex_email, $email_addr)) return true;
		else if (eregi($this->regex_email2, $email_addr)) return true;
		else {
			$this->addError("Invalid E-mail Address: $email_addr");
			return false;
		}
	}

		//Verifies that the body portion of message matches a given
		// regular expression.  Nice for setting a minimum message length.
	function verify_body($body){
		if (eregi($this->regex_body, $body)) return true;
		else {
			$this->addError("Invalid Body Content: $body");
			return false;
		}
	}

		//Verifies that the subject portion of message matches a given
		// regular expression.  Nice for setting a minimum subject length.
	function verify_subject($subject){
		if (eregi($this->regex_subject, $subject)) return true;
		else {
			$this->addError("Invalid Subject Content: $subject");
			return false;
		}
	}

/******************************************************************************\
\******************************************************************************/


	//Close Class Definition
}

Usage Examples:

/******************************************************************************\
--
--	Program Use Examples
--		Purpose: The following are a few examples on using the eMail class in
--			an application.
--
\******************************************************************************/
/******************************************************************************\

Example 1:  Basic Text E-mail
		//Initialize e-mail object
	$email = new eMail();

		//Add a To recipient
	$email->addTo("example@example.com");

		//Add a subject for the e-mail
	$email->subject = "Test E-mail Subject";

		//Set the body portion of the e-mail
	$email->setBody('
	This is a text body in an e-mail.
	Nothing else is required, it can now be sent.
	');

		//Send the e-mail
	$email->sendMail();

--------------------------------------------------------------------------------

Example 2:  Basic Html E-mail
		//Initialize e-mail object
	$email = new eMail();

		//Add a To recipient
	$email->addTo("example@example.com");

		//Add a subject for the e-mail
	$email->subject = "Test E-mail Subject";

		//Set the body portion of the e-mail, setting it to HTML with the
		// second parameter.
	$email->setBody('
	This is now a html body in an e-mail.<HR>
	Nothing else is required, it can now be sent.
	', true);

		//Send the e-mail
	$email->sendMail();

--------------------------------------------------------------------------------

Example 3:  Basic Attachment Example with an Html body
		//Initialize e-mail object
	$email = new eMail();

		//Add a To recipient
	$email->addTo("example@example.com");

		//Add a subject for the e-mail
	$email->subject = "Test E-mail Subject";

		//Set the body portion of the e-mail, setting it to HTML with the
		// second parameter.
	$email->setBody('
	This is now a html body in an e-mail.<HR>
	Nothing else is required, it can now be sent.
	', true);

		//Add an attachment to the e-mail
	$email->addAttachment("Text in the attachment","filename.txt","text/plain");

		//Send the e-mail
	$email->sendMail();

--------------------------------------------------------------------------------

Example 4:  Multiple Attachments
		//Initialize e-mail object
	$email = new eMail();

		//Add a To recipient
	$email->addTo("example@example.com");

		//Add a subject for the e-mail
	$email->subject = "Test E-mail Subject";

		//Set the body portion of the e-mail, setting it to HTML with the
		// second parameter.
	$email->setBody('
	This is now a html body in an e-mail.<HR>
	Nothing else is required, it can now be sent.
	', true);

		//Attach an html file containing the body of the message
	$email->addAttachment($email->body,"email_body.html","text/html");

		//Attach a second file
	$email->addAttachment("File Data","Attachment01.txt");

		//Send the e-mail
	$email->sendMail();

\******************************************************************************/
?>

Useful Links:

Advertisement

Leave a Reply