#native_company# #native_desc#

Sending MIME Email With PHP Page 5

By Kartic Krishnamurthy
on August 7, 2000

The next method we will be examining, build_message(), does the bulk of all this work but is invoked via one gen_email() method. Please note that build_message() is a private method.


function build_message() {

    $msg "";

$boundary 'PM'.chr(rand(6591)).'------'.md5(uniqid(rand()));    # Boundary marker

$nparts sizeof($this->mimeparts);

 // Case 1: Attachment list is there.  Therefore MIME Message header must have multipart/mixed

if (is_array($this->mimeparts) && ($nparts 1)) {

$c_ver "MIME-Version: 1.0".CRLF;

$c_type 'Content-Type: multipart/mixed;'.CRLF."tboundary="$boundary"".CRLF;

$c_enc "Content-Transfer-Encoding: ".BIT7.CRLF;

$c_desc $c_desc?"Content-Description: $c_desc".CRLF:"";


 // Since we are here, it means we do have attachments => body must become an attachment too.

if (!empty($this->body)) {



 // Now create the MIME parts of the email!

for ($i=$i $nparts$i++) {

            if (!empty(

$msg .= CRLF.'--'.$boundary.CRLF.$this->mimeparts[$i].CRLF;


$msg .= '--'.$boundary.'--'.CRLF;

$msg $c_ver.$c_type.$c_enc.$c_desc.$warning.$msg;

    } else {

        if (!empty(
$this->body)) $msg .= $this->body.CRLF.CRLF;





This method is kind of a paradox, it is simple yet complex. Read on to see for yourself.
  1. We read earlier (under MIME Basics), that each MIME part has a boundary marker and that the marker is a unique id. The boundary marker is used in:
    • the MIME Message header to denote where the attachments must be demarcated
    • the MIME parts: actually before and after each part to delimit that attachment boundary. (Refer back to Alexander’s email with the image and pedigree chart!)

    (Remember: The last boundary marker ends in two hyphens (–) to denote end of scope).
    $boundary contains the boundary marker and is the MD5 hash of the unique id of a random number. Additionally, we also prefix a “PM?” to $boundary, where “?” is a random alphabet. An example value for $boundary is "PMK------2345ee5de0052eba4daf47287953d37e"(PM stands for PHP MIME, so you can change this to your initials may be!)

  2. We must consider two cases during the process of generation MIME headers. These cases affect the way in which the original body of the mail ($body in the constructor) is treated and the very presence of MIME headers.
    • Case 1 is the reason why this article was written and you are reading it: There are attachments available to be included! In this case, please note that what would have been the body of the message is occupied by the warning string "This is a MIME Encoded Message". Hence, the actual message body itself must be added as an attachment to this message! The email text usually is the first attachment in the list of attachments, which is $mimeparts[0] in our case. That is precisely the reason why we bumped up an index in $mimeparts so that the first slot (subscript 0) is available for the email text part. The email body must be attached as text/plain with 7bit encoding.
    • <?php

      if (!empty($this->body)) {




      The above snippet does this job of attaching the email text part as a MIME attachment. Note that we are using the ‘BODY’ constant to indicate to attach() where to attach it.

  3. Case 2 is when there are no attachment, in which the case, the email text, if supplied, is the only information that is included in the local variable $msg; no MIME headers are needed in this case. (However, we could have specified just the MIME-Version header in this case – rewind back to the simplest MIME message presented earlier.)
  4. The MIME message headers (MIME-Version, Content-Type, etc.) are created if there are attachments. To create the message body with the MIME Message headers, first the MIME message headers are created. Then the individual MIME parts available through the $mimeheaders array are processed in iteration. This is the point where the boundary marker ($boundary) is actually used. In conformance with the rules, two hyphens are prefixed (>'--'.$boundary.CRLF) for a MIME part and additionally, two hyphens are appended to the boundary marker ('--'.$boundary.'--'.CRLF;) after the last MIME part to indicate the end-of-scope.
  5. The completed message in the variable $msg is the return value of this method.
The next method, gen_email() completes (well, more or less) the MIME message created by the build_message() method. Since build_message() is an internal method, gen_email () creates the RFC 822 headers and appends the MIME information after a call to build_message().


function gen_email($force=false) {

if (!empty($this->email) && !$force) return $this->email ;  // saves processing

$email "";

    if (empty(
$this->subject)) $this->subject NOSUBJECT;

    if (!empty(
$this->from)) $email .= 'From: '.$this->from.CRLF;

    if (!empty(
$this->headers)) $email .= $this->headers.CRLF;

$email .= $this->build_message();

$this->email $email;




The class member $email has the entire email message generated for an instance of our class. To avoid unnecessary recreation of the message, this method proceeds to create the email headers and to call build_message() only if $email is empty. However, you can force reprocessing by calling gen_email(true). (The caller will definitely want to do this if the “To” information is changed or a new attachment is added).
gen_email() creates the more familiar From header. Additionally it sets the subject to a generic (No Subject) if no subject was specified at all. We save the inclusion of the To and Subject headers until later. The method returns the completed email message and this concludes the task of creating the MIME message.