A Better Way to Determine MIME Types for MIME Email with PHP

Welcome to the third episode of the series entitled “Sending MIME email with PHP.” This series progressively teaches you how to construct a reusable MIME mailer class that can be easily integrated into your existing PHP applications. In this article, I’ll be modifying the implementation of the “getMimeTypes()” method, included with this mailer class, in order to make it more compact and efficient.

If you’re a PHP developer who has spent a long time building web applications, then you’re probably aware of the remarkable capabilities offered by email. This capacity has been built around the PHP native “mail()” function, which, as you know, facilitates the development of email-related scripts.

However, this beautiful and peaceful scenario can quickly turn into a raging storm, specifically in those cases when you need to send email messages in HTML format and work with attachments. Here’s where MIME comes in handy, since this mail extension allows you to perform all of these tasks with minor hassles, even though it might take some time to master its most complex features.

However, if you’re interested in learning how to use an object-oriented approach to build a highly modular PHP class that sends fully-compliant MIME email messages, while also working with file attachments, you’ve come to the right place.

And now that you’ve been introduced to the principal subject of this PHP series, let me briefly refresh the topics that I discussed in the last article, in case that you’ve not had the chance to read it. In it, I demonstrated how to build a modular MIME mailer class in PHP 4; it was provided with the capacity to send messages in plain text, and to work with different types of file attachments.

This class implements a private method, called “getMimeTypes(),” which, as its name would suggest, comes in handy for determining the correct MIME type of a given file. As you know, this process is required to assemble the different parts of a multi-part MIME-based message correctly. However, the logic implemented by this method is rather primitive and can definitely be improved.

Are you ready to continue this educational journey? Let’s get started!

{mospagebreak title=Review: sending MIME-compliant email messages with PHP 4}

Since my plan for this tutorial consists primarily of improving the implementation of the “getMimeTypes()” method that was coded in the preceding article, this is the appropriate moment to list its corresponding definition, before I start modifying the method in question.

Here’s how the pertaining “Mailer” class looked previously:


class Mailer{

var $sender;

var $recipient;

var $subject;

var $headers=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′;

}

// create text part of the message

function buildTextPart(){

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

}

// 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;

}

}

// 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";

}

// add new MIME header

function addHeader($name,$value){

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

}

// 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){

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

switch(strtolower($nameArray[count($nameArray)-1])){

case ‘jpg’:

$mimeType=’image/jpeg’;

break;

case ‘jpeg’:

$mimeType=’image/jpeg’;

break;

case ‘gif’:

$mimeType=’image/gif’;

break;

case ‘txt’:

$mimeType=’text/plain’;

break;

case ‘pdf’:

$mimeType=’application/pdf’;

break;

case ‘csv’;

$mimeType=’text/csv’;

break;

case ‘html’:

$mimeType=’text/html’;

break;

case ‘htm’:

$mimeType=’text/html’;

break;

case ‘xml’:

$mimeType=’text/xml’;

break;

}

return $mimeType;

}

// send email

function send(){

$to=$this->recipient;

$subject=$this->subject;

$headers=$this->buildHeaders();

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

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

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

  }

}

}


It won’t hurt anybody if I also create a basic script that demonstrates how to use the above class, right? Take a look at the script below:


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

$mailer=&new Mailer(‘alejandro@mydomain.com,’mybuddy@yourdomain.com’,'Testing mailer class’,'Hello buddy. I am sending to you a couple of attachments.’);

// add some attachments

$mailer->addAttachment(‘image1.jpg’);

$mailer->addAttachment(‘image2.jpg’);

// send MIME email

$mailer->send();

As you can see, the previous MIME mailer class does a decent job when it comes to sending messages in plain text format and attaching the most common types of files, like JPG and GIF images, PDF and HTML documents, and so forth.

Nonetheless, the implementation of the “getMimeType()” method still doesn’t convince me, since determining MIME types of the attached files can be done more efficiently by assigning a few simple class properties.

Therefore, in the following section, I’m going to show you how to modify the signature of the aforementioned “getMimeType()” method in order to improve the overall structure of the mailer class that was listed a few lines above.

To learn about how this will be done, please click on the link below and keep reading.

{mospagebreak title=Modifying the signature of the “Mailer” class}

As I mentioned earlier, it’d be pretty convenient to slightly modify the existing signature of the “Mailer” class in order to save all of the MIME types allowed by it in a simple array. In doing so, not only will its private “getMimeType()” method be much easier to code, but the incorporation of other supported MIME types will merely be a matter of adding more elements to the mentioned array.

Of course, all of this theory must be translated into concrete PHP code. Therefore, have a look at the improved definition of the “Mailer” class, which includes all of the changes explained earlier:


class Mailer{

var $sender;

var $recipient;

var $subject;

var $headers=array();

var $mimeTypes=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']=’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’;

}

// create text part of the message

function buildTextPart(){

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

}

// 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;

}

}

// 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";

}

// add new MIME header

function addHeader($name,$value){

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

}

// 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;

}

// send email

function send(){

$to=$this->recipient;

$subject=$this->subject;

$headers=$this->buildHeaders();

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

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

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

  }

}

}


Well, at this point you’ll have to agree that the business logic has been dramatically improved. And the reason is that now the class stores all the allowed MIME types as an array of properties, called “$mimeTypes.”

The immediate advantages are: if a new MIME type needs to be supported by the class, the process is reduced to adding a new element to the corresponding “$mimeTypes” array. And the implementation of the “getMimeType()” private method is much simpler and tighter.

So far, so good. At this point, I’ve showed you how to improve the initial signature of this MIME mailer class by way of a simple property. Though, I’m sure that after introducing this minor modification you’ll want to see how it functions.

In the final section of this tutorial, I’m going to setup an illustrative example for you that shows the class in action. Of course, to see how the example in question will be created, you’ll have to click on the link below and keep reading.

{mospagebreak title=Putting the modified “Mailer” class to work}

Below I coded a final hands-on example that demonstrates how to use the “Mailer” class, after its original signature has been modified.

Here is the corresponding code sample:


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

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

// add some attachments

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

$mailer->addAttachment(‘file.jpg’);

// send MIME email

$mailer->send();


As you can see, changing the way  the “Mailer” class does some of its things doesn’t imply that its API must change too. The above example demonstrates this concept very clearly, since the steps taken to use the class in question are the same steps you learned in the two previous tutorials of the series.

And lastly, here’s my final suggestion: feel free to introduce your own modifications to the pertaining “Mailer” class, not only to extend its functionality, but to improve your background in sending MIME email with PHP.

Final thoughts

In this third episode of the series, I showed you how to improve the business logic of the previous MIME mailer class, specifically when it comes to determining the MIME type of the attached files. As you saw before, this process was performed by creating an additional array of class properties. So you shouldn’t have major problems understanding how it functions.

In the next article, I’m going to continue extending the functionality of this MIME mailer class by providing it with the capacity to send email messages in HTML format.

The article will be insightful, trust me. I hope you don’t miss the upcoming tutorial!

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan