January 28, 2009

Sending mail Attachment(s) with PHP mail function (PART -I) : Rules Of Thumb

A few days ago I was writing a script that would send email with (or without) any number of attachments. I started googling for help and ended up with some code snippets that didn’t work. After spending few more frustrating hours debugging those scripts, I finally reached the solution (“Tank you! Anand, Kunal and Avlesh… for your suggestions”). The problem with those scripts was that they were missing some crucial pieces of mail header and it was really a daunting task to fix those bugs, because “trial 'n error” was the only option left. That’s why in this post I tried to formulate a set of rules to send mail using mail() function with or without any attachment.

The Rules:

  1. In the mail header few header elements (like "Form ", "Cc " , "Bcc", "'MIME-Version" ) will remain as it is, irrespective of the fact that the mail has any attachment or not.
  1. a. If a mail doesn't contain any attachment, then Content-type will be "text/html" (for html formatted mail) or "text/plain" ( for plain text mail) . Content-type should have an additional attribute "charset" to define character encoding of the message.

b. In case when mail consists of one or more attachments, Content-type will be "multipart/mixed". Content-type will also have an attribute called "boundary". The "boundary" attribute contains a unique signature which is use to denote the starting point of each message/attachment of the mail as well as the end of mail.

  1. a. In case of mail without attachment the message string should be passed to mail function as message parameter.

b. If mail contains one or more attachments, then the message and the attachment file contents will be attached to the header string, separated by a boundary notation

-- [boundary value]

the start message will also have similar boundary notation to denote the start of message and A blank string or null value should be passed to the message parameter of mail function.

  1. In multipart mail each message/attachment will have their own Content-type . For a multipart mail header the message will have Content-type "text/html" (for html formatted mail) or "text/plain" (for plain text mail). And attachment will have Content-type depending upon the type of content. If you are not sure about content use Content-type "application/octet-stream". For attachment content type Additional Attribute name can be use to denote the base name of the attachment file.
  1. Each attachment block also contain header "Content-Transfer-Encoding" to specify the content encoding
  1. Each attachment block will have Content-Disposition as "attachment" and attribute filename will denote the name of the downloaded file.
  1. After the end of all attachments there will be end of mail notation

--[boundary value]--



Note : To be on the safe side it is better to encode the attachment content to some standard encoding and set the Content-Transfer-Encoding as per the implemented encoding.

In the next Post we will see how to implement these Rules in actual code

(c) Sourav Ray Creative Commons License

1 comment: