Migrating Class Code for a MIME Email to PHP 5

Welcome to the final installment of the series, “Sending MIME email with PHP.” This series teaches you how to build a highly modular PHP class that can be used to send MIME-compliant email messages in plain text and HTML, while letting you work with file attachments as well. In this article, I’m going to migrate the source code from the previous article to PHP 5, taking full advantage of the new and improved features in the latest version of PHP.

One of the easiest tasks to perform with PHP is sending email to one or more recipients, thanks to its popular built-in “mail()” function. However, if you’re armed with the right background, it’s relatively simple to build an entire mailer class using this function, so that you can take advantage of the MIME extension.

This mail extension permits, among other things, sending messages in HTML format and handling different types of file attachments, which you’ve surely done hundreds of times before while using your favorite email client. Nonetheless, if you’re interested in learning how to do all of these useful things by utilizing a single PHP class, then start reading this group of articles!

At this point I’m assuming that you already read the last article of this series, so you’ll surely recall that I completed the development of a MIME mailer class provided with the capacity to sending email messages in HTML and plain text format. It also had the ability to handle a decent number of file attachments. While this mailer class can be used with small PHP applications, it lacks some important features related specifically to its object model, since it was built in PHP 4 from the very beginning.

So are you ready to learn how to port the full source code of this MIME mailer class to PHP 5? Let’s begin now!

{mospagebreak title=Sending MIME email with PHP 4}

Before I start showing you how to migrate the source code of the MIME mailer class that I built in the previous article to PHP 5 , it’d be pretty useful to list its entire definition. This way you’ll be able to compare this PHP-4 based version of the class with the one that will be coded later on using PHP 5.

Having said that, here’s how the pertinent “Mailer” class looks before making the aforementioned code migration:


class Mailer{

var $sender;

var $recipient;

var $subject;

var $headers=array();

var $mimeTypes=array();

var $html=array();

var $attachments=array();

function Mailer($sender,$recipient,$subject,$message){

// validate incoming parameters

if(!preg_match("/^.+@.+$/",$sender)){

trigger_error(‘Invalid value for email sender.’);

}

if(!preg_match("/^.+@.+$/",$recipient)){

trigger_error(‘Invalid value for email recipient.’);

}

if(!$subject||strlen($subject)>255){

trigger_error(‘Invalid length for email subject.’);

}

if(!$message){

trigger_error(‘Invalid value for email message.’);

}

$this->sender=$sender;

$this->recipient=$recipient;

$this->subject=$subject;

$this->message=$message;

// define some default MIME headers

$this->headers['MIME-Version']=’1.0′;

$this->headers['Content-Type']=’multipart/mixed;boundary="MIME_BOUNDRY"’;

$this->headers['From']=’<’.$this->sender.’>’;

$this->headers['Return-Path']=’<’.$this->sender.’>’;

$this->headers['Reply-To']=$this->sender;

$this->headers['X-Mailer']=’PHP 4/5′;

$this->headers['X-Sender']=$this->sender;

$this->headers['X-Priority']=’3′;

// define some default MIME types

$this->mimeTypes['image/jpeg']=’jpg’;

$this->mimeTypes['image/jpg']=’jpg’;

$this->mimeTypes['image/gif']=’gif’;

$this->mimeTypes['text/plain']=’txt’;

$this->mimeTypes['text/html']=’htm’;

$this->mimeTypes['text/xml']=’xml’;

$this->mimeTypes['application/pdf']=’pdf’;

}

// add new MIME header

function addHeader($name,$value){

$this->headers[$name]=$value;

}

// add HTML to message

function addHTML($html){

if(!$html){

trigger_error(‘Invalid HTML.’,E_USER_ERROR);

}

$this->html[]=$html;

}

// add new attachment

function addAttachment($attachment){

if(!file_exists($attachment)){

trigger_error(‘Invalid attachment.’,E_USER_ERROR);

}

$this->attachments[]=$attachment;

}

// get MIME Type of attachment

function getMimeType($attachment){

$attachment=explode(‘.’,basename($attachment));

if(!$mimeType=array_search(strtolower($attachment[count($attachment)-
1]),$this->mimeTypes)){

trigger_error(‘MIME Type not found.’,E_USER_ERROR);

}

return $mimeType;

}

// create message MIME headers

function buildHeaders(){

foreach($this->headers as $name=>$value){

$headers[]=$name.’: ‘.$value;

}

return implode("n",$headers)."nThis is a multi-part message in MIME format.n";

}

// create text part of the message

function buildTextPart(){

return "–MIME_BOUNDRYnContent-Type: text/plain; charset=iso-8859-1
nContent-Transfer-Encoding: quoted-printablennn".$this->message."nn";

}

// create HTML part of the message

function buildHTMLPart(){

if(count($this->html)>0){

$htmlPart=”;

foreach($this->html as $html){

$htmlPart.="–MIME_BOUNDRYnContent-Type: text/html; charset=iso-8859-1
nContent-Transfer-Encoding: 8bitnnn".$html."nn";

}

return $htmlPart;

}

}

// create attachments part of the message

function buildAttachmentPart(){

if(count($this->attachments)>0){

$attachmentPart=”;

foreach($this->attachments as $attachment){

$fileStr=file_get_contents($attachment);

$fileStr=chunk_split(base64_encode($fileStr));

$attachmentPart.="–MIME_BOUNDRYnContent-Type: ".$this->getMimeType
($attachment)."; name="".basename($attachment).""nContent-disposition:
attachmentnContent-Transfer-Encoding: base64nn".$fileStr."nn";

}

return $attachmentPart;

}

}

// send email

function send(){

$to=$this->recipient;

$subject=$this->subject;

$headers=$this->buildHeaders();

$message=$this->buildTextPart().$this->buildHTMLPart().$this-
>buildAttachmentPart()."–MIME_BOUNDRY–n";

if(!mail($to,$subject,$message,$headers)){

trigger_error(‘Error sending email.’,E_USER_ERROR);

}

}

}


That’s was pretty illustrative, right? Having listed the full source code that corresponds to the MIME mailer class that was constructed in the last tutorial, I should assume that you’re very familiar with using it to send messages in plain text and HTML format, while working with file attachments also.

So what’s the next step? Well, as I said in the introduction, it’d be pretty convenient to port the entire source code of the above mailer class to PHP 5. This would permit us to take advantage of its improved object model.

Therefore, in the following section, I’m going to show you how to perform the aforementioned code migration. To learn the details of this process, please click on the link below and keep reading.

{mospagebreak title=Porting the code of the previous MIME mailer class to PHP 5}

Porting the source code of the previous “Mailer” class to PHP 5 is actually a very simple process, since all that it requires is using the correct syntax, and changing some statements of the class.

However, this procedure will be better understood if you have a look at the definition of the brand new MIME mailer class listed below. It has now been properly migrated to PHP 5. Here it is:


class Mailer{

private $sender;

private $recipient;

private $subject;

private $headers=array();

private $mimeTypes=array();

private $html=array();

private $attachments=array();

public function __construct($sender,$recipient,$subject,$message){

// validate incoming parameters

if(!preg_match("/^.+@.+$/",$sender)){

throw new Exception(‘Invalid value for email sender.’);

}

if(!preg_match("/^.+@.+$/",$recipient)){

throw new Exception(‘Invalid value for email recipient.’);

}

if(!$subject||strlen($subject)>255){

throw new Exception(‘Invalid length for email subject.’);

}

if(!$message){

throw new Exception(‘Invalid value for email message.’);

}

$this->sender=$sender;

$this->recipient=$recipient;

$this->subject=$subject;

$this->message=$message;

// define some default MIME headers

$this->headers['MIME-Version']=’1.0′;

$this->headers['Content-Type']=’multipart/mixed;boundary="MIME_BOUNDRY"’;

$this->headers['From']=’<’.$this->sender.’>’;

$this->headers['Return-Path']=’<’.$this->sender.’>’;

$this->headers['Reply-To']=$this->sender;

$this->headers['X-Mailer']=’PHP5′;

$this->headers['X-Sender']=$this->sender;

$this->headers['X-Priority']=’3′;

// define some default MIME types

$this->mimeTypes['image/jpeg']=’jpg’;

$this->mimeTypes['image/jpg']=’jpg’;

$this->mimeTypes['image/gif']=’gif’;

$this->mimeTypes['text/plain']=’txt’;

$this->mimeTypes['text/html']=’htm’;

$this->mimeTypes['text/xml']=’xml’;

$this->mimeTypes['application/pdf']=’pdf’;

}

// add new MIME header

public function addHeader($name,$value){

$this->headers[$name]=$value;

}

// add HTML to message

public function addHTML($html){

if(!$html){

throw new Exception(‘Invalid HTML.’);

}

$this->html[]=$html;

}

// add new attachment

public function addAttachment($attachment){

if(!file_exists($attachment)){

throw new Exception(‘Invalid attachment.’);

}

$this->attachments[]=$attachment;

}

// get MIME Type of attachment

private function getMimeType($attachment){

$attachment=explode(‘.’,basename($attachment));

if(!$mimeType=array_search(strtolower($attachment[count($attachment)-
1]),$this->mimeTypes)){

throw new Exception(‘MIME Type not found.’);

}

return $mimeType;

}

// create message MIME headers

private function buildHeaders(){

foreach($this->headers as $name=>$value){

$headers[]=$name.’: ‘.$value;

}

return implode("n",$headers)."nThis is a multi-part message in MIME format.n";

}

// create text part of the message

private function buildTextPart(){

return "–MIME_BOUNDRYnContent-Type: text/plain; charset=iso-8859-1
nContent-Transfer-Encoding: quoted-printablennn".$this->message."nn";

}

// create HTML part of the message

private function buildHTMLPart(){

if(count($this->html)>0){

$htmlPart=”;

foreach($this->html as $html){

$htmlPart.="–MIME_BOUNDRYnContent-Type: text/html; charset=iso-8859-1
nContent-Transfer-Encoding: 8bitnnn".$html."nn";

}

return $htmlPart;

}

}

// create attachments part of the message

private function buildAttachmentPart(){

if(count($this->attachments)>0){

$attachmentPart=”;

foreach($this->attachments as $attachment){

if(!$fileStr=file_get_contents($attachment)){

throw new Exception(‘Error reading contents of attachment.’);

}

$fileStr=chunk_split(base64_encode($fileStr));

$attachmentPart.="–MIME_BOUNDRYnContent-Type: ".$this->getMimeType
($attachment)."; name="".basename($attachment).""nContent-disposition:
attachmentnContent-Transfer-Encoding: base64nn".$fileStr."nn";

}

return $attachmentPart;

}

}

// send email

public function send(){

$to=$this->recipient;

$subject=$this->subject;

$headers=$this->buildHeaders();

$message=$this->buildTextPart().$this->buildHTMLPart().$this-
>buildAttachmentPart()."–MIME_BOUNDRY–n";

if(!mail($to,$subject,$message,$headers)){

throw new Exception(‘Error sending email.’);

}

}

}


The PHP 5 version of the MIME mailer class doesn’t differ much from its counterpart coded in PHP 4. Of course, I used the syntax supported by PHP 5 in order to implement the different methods of the class. I also utilized a few simple exceptions to handle basically all of the errors that might occur during its execution. But other than the mentioned modifications, the signature of the class remains nearly the same.

Well, I showed you how to recode the pertaining “Mailer” class with PHP 5, a process that hopefully didn’t cause you major headaches. Therefore, the only thing left to do is develop an illustrational example that shows how to use the class in question.

As you might have guessed, this hands-on example will be created in the final section of this article, so jump forward and read the next few lines. I’ll be there waiting for you.

{mospagebreak title=Putting the brand new mailer class to work}

In accordance with the concepts expressed in the previous section, I’ve set up a practical example aimed at demonstrating the functionality offered by the MIME mailer class now that it has been migrated to PHP 5.

The pertaining code sample looks like this:


try{

// create a new instance of the ‘Mailer’ class

$mailer=new Mailer
(‘alejandro@mydomain.com’,'somebuddy@yourdomain.com,’Testing the mailer
class’,'Hey, I am sending you a couple of fun images.’);

// add some HTML to the message

$mailer->addHTML(‘<strong>This text is formatted with HTML</strong>’);

// add some attachments

$mailer->addAttachment(‘file1.gif’);

$mailer->addAttachment(‘file2.gif’);

// send MIME email

$mailer->send();

}

catch(Exception $e){

echo $e->getMessage();

exit();

}


As you can see, the API of the “Mailer” class allows us to send email messages in both plain text and HTML formats. And if all of these features aren’t good enough for you, it also handles file attachments in a simple way.

Finally, I recommend you tweak the source code of this class and incorporate your own modifications in order to suit your personal requirements.

Final thoughts

It’s hard to believe, but we’ve come to the end of this journey. I hope the whole experience has been instructive, since I simply tried to provide you with some useful pointers to help you start using MIME email within your own PHP applications. In a case like this, I used an object-oriented approach to send email, but you can utilize a procedural methodology and obtain practically the same results.

See you in the next PHP development tutorial!

Google+ Comments

Google+ Comments