previousMail_Mime::setTxtBody() (Previous) (Next) Mail_mimePart::Mail_mimePart()next

View this page in Last updated: Sun, 18 Oct 2009
English | Brazilian Portuguese | Chinese | Dutch | French | German | Hungarian | Japanese | Polish | Russian | Spanish | Turkish

Mail_Mime - Example

Mail_Mime - Example – generation and sending of a MIME mail

Example

<?php
include('Mail.php');
include(
'Mail/mime.php');

$text 'Text version of email';
$html '<html><body>HTML version of email</body></html>';
$file '/home/richard/example.php';
$crlf "\n";
$hdrs = array(
              
'From'    => 'you@yourdomain.com',
              
'Subject' => 'Test mime message'
              
);

$mime = new Mail_mime($crlf);

$mime->setTXTBody($text);
$mime->setHTMLBody($html);
$mime->addAttachment($file'text/plain');

//do not ever try to call these lines in reverse order
$body $mime->get();
$hdrs $mime->headers($hdrs);

$mail =& Mail::factory('mail');
$mail->send('postmaster@localhost'$hdrs$body);
?>
previousMail_Mime::setTxtBody() (Previous) (Next) Mail_mimePart::Mail_mimePart()next

Download Documentation Last updated: Sun, 18 Oct 2009
Do you think that something on this page is wrong? Please file a bug report or add a note.
User Notes:
Note by: robert.johnson@icap.com
Looking at NWDev's comment below, '\r\n' is never going to expand into cr-lf, it should be in double quotes: "\r\n"
Note by: mk@digitaleprodukte.de
I had problems, when attaching a file to an e-mail:
<code>
$mime = new Mail_mime("\n");
$mime->setTXTBody($txtBody);
$mime->setHTMLBody($htmlBody);

if (is_array($attachments)) {
foreach($attachments as $attachment) {
$mime->addAttachment($attachment["file"], $attachment["contentType"], $attachment["name"], $attachment["isFile"], $attachment["encoding"]);
}
}

$mailBody = $mime->get($_build_params);
$mailHeaders = $mime->headers($mailHeaders);

$mail =& Mail::factory($this->backend, $this->backendParams);

$mail->send($this->recip, $mailHeaders, $mailBody);
</code>

In this use case the mail was sent, but nearly all webmailers and e-mail programs did not show the attachment(s). I analysed the source code of the sent e-mails and I saw that the same boundaries were used for different e-mail parts (here "_d188467fafaf9f24df2e4585a2d76019"):
<code>
To: [E-MAIL-ADDRESS]
Subject: [SUBJECT]
MIME-Version: 1.0
From: [ANOTHER E-MAIL-ADDRESS]
Content-Type: multipart/mixed;
boundary="=_d188467fafaf9f24df2e4585a2d76019"
Date: Thu, 17 Sep 2009 17:37:41 +0200 (CEST)

--_d188467fafaf9f24df2e4585a2d76019
Content-Type: multipart/alternative;
boundary="=_d188467fafaf9f24df2e4585a2d76019"

--=_d188467fafaf9f24df2e4585a2d76019
Content-Transfer-Encoding: base64
Content-Type: text/plain; charset="utf-8"

[CONTENT]
--=_d188467fafaf9f24df2e4585a2d76019
Content-Transfer-Encoding: base64
Content-Type: text/html; charset="utf-8"

[CONTENT]
--=_d188467fafaf9f24df2e4585a2d76019--

--=_d188467fafaf9f24df2e4585a2d76019
Content-Transfer-Encoding: base64
Content-Type: application/pdf;
name="file.pdf";
Content-Disposition: attachment;
filename="file.pdf";

[CONTENT]
--_d188467fafaf9f24df2e4585a2d76019--
</code>

So, I wrote a simple (not optimal) workaround (only tested for one attachment, further tests required, or better: Mail_mime should be corrected, if this is a bug):
<code>
$mailBody = $mime->get($_build_params);
$mailHeaders = $mime->headers($mailHeaders);

// Workaround, because, if attachments exist the same boundary is used for several e-mail parts
if (sizeof($this->attachments) > 0) {
preg_match("/boundary=\"(.[^\"]*)\"/e", $mailHeaders["Content-Type"], $boundary);
$boundary = $boundary[1];
$bounderyNew = $bounderyNew;
$mailHeaders["Content-Type"] = preg_replace('/boundary="(.[^"]*)"/', 'boundary="' . $bounderyNew . '"', $mailHeaders["Content-Type"]);
$mailBody = preg_replace("/^\-\-" . $boundary . "/s", "--" . $bounderyNew, $mailBody);
$mailBody = preg_replace("/" . $boundary . "--$/s", $bounderyNew . "--", $mailBody);
$mailBody = preg_replace("/" . $boundary . "--(\s*)--" . $boundary . "/s", $boundary . "--$1--" . $bounderyNew, $mailBody);
}

// Workaround, because "\r" breaks the e-mails (possibly a problem with Pear::Mail_Mime and Postfix)
foreach($mailHeaders as $key=>$header) {
$mailHeaders[$key] = str_replace("\r\n", "\n", $header);
}

$mail =& Mail::factory($this->backend, $this->backendParams);
</code>

This changes the boundary of the toplevel e-mail parts.
Note by: NWdev
When setting the $crlf parameter, don't set the value like so:

<code>
define('CRLF','\r\n');
...
$mime = new Mail_mime(CRLF);
...
</code>

In my case, passing the CRLF constant (versus a variable or the actual "\r\n" text) resulted in an email that appeared to have the correct \r\n terminating lines but the content came through as plain text (it was a multi-part HTML & text email).

So use this instead if you're defining your CRLF constant and save a lot of head-banging:

<code>
define('CRLF','\r\n');
...
$crlf = CRLF;
$mime = new Mail_mime($crlf);
...
</code>

Or, of course just pass the value directly...

<code>
$mime = new Mail_mime('\r\n');
</code>
Note by: wiesemann
@buddy..., the send() method belongs to the Mail package, not to the Mail_mime package. If you look into the documentation for Mail, you'll find out that send() returns a PEAR_Error instance in case of an error. Therefore, the correct error checking is like this:
$res = $mail->send(...);
if (PEAR::isError($res)) {
// error
} else {
// success
}

=> http://pear.php.net/manual/en/package.mail.mail.send.php
Note by: buddy@databoysoftware.com
I notice that no where do I find simple error handling.
Correct me if I am wrong, but I think this should work:
if($mail_object->send($recipients, $headers, $message))
{
it worked
}
else
{
it didn't work
}
Note by: consulting@arlyle.com
It's a common mistake to think that "\n" is sufficient, BUT IT IS NOT! That's because the SMTP standard specifies that all lines MUST be terminated by "\r\n", not just "\n" or just "\r". Some SMTP daemons have a problem if you only use "\n".

That's why the default behavior of the class is to use "\r\n" and it really shouldn't be overridden.
Note by: Deger
I couldn't come accross to any smtp method examples and it took me a while to learn how to use this package. I hope this message ripens this pear package end-user manual a wee bit more making it ready to eat, straight from branch.

SMTP Example:
Please Note:
Auth_SSL is a dependent package here. You may get it like this: pear install --alldeps Mail_Mime-1.4.0.tgz

<?php
$your_html_message 
'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"      "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>Hello World!</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>'
;
// Require Pear Mail Packages
require_once ("Mail.php");
require_once (
"Mail/mime.php");
$recipients  'Deger <Deger@bogusdomain.con>';
// Additional headers
$headers["From"] = 'Deger <Deger@bogusdomain.con>';
$headers["To"]    = 'Deger <Deger@bogusdomain.con>'
$headers["Subject"] = "Ready To Eat Pears";
$crlf "\n";
$mime = new Mail_mime($crlf);

$mime->setHTMLBody($your_html_message);
$message $mime->get();
$headers $mime->headers($headers);
$params["host"]    = 'mail.bogusdomain.con';
$params["auth"]    = TRUE// note: there are *no delimiters*

// note: there are *no delimiters* for DIGEST-MD5 either. 
// If you want to use PLAIN,
// you have to use delimiters like this: 'PLAIN'
$params["auth"]    = DIGEST-MD5
$params["username"]    = 'yourusername';
$params["password"]    = 'yourpassword';
$params["localhost"]= 'This.may.be.yourIP';
// Debug so that we see what's happenning for the moment.
$params["debug"]    = "True"
// create the mail object using the Mail::factory method
$mail_message =& Mail::factory('smtp'$params);
$mail_message->send ($recipients$headers$message);
?>
Note by: jb@fusionquest.com
With regard to $mime->headers($hdrs);...

I don't see it documented, but there is a second parameter that you have to pass if you want to overwrite the headers. For example, your script sends one email. Then, you want to send another email to someone else with different subject line. By default, mime will use the previous headers sent. If you want to overwrite them, you need to do this:
$mime->headers($hdrs, true);
Note by: josh@ionexinteractive.com
There's a difference between '\n' and "\n". With single quotes, PHP interprets that as a LITERAL string. Double quotes are for INTERPRETED strings.

Thus, passing '\n' spits out exactly \n.

Passing "\n" spits out the actual carriage return/line feed code needed to create a new line.

If you want a single line separator (like one <br />), just pass one "\n". If you want a blank line space between things (i.e. <br /> <br />), pass "\n\n". And so on for three, four, five, whatever lines.

Usage example:
$message = 'Hello';
$message .= "\n\n".'World!';

require_once('Mail.php');
require_once('Mail/mime.php');

$crlf = "\n"; //note the DOUBLE quotes.
$hdrs = array (
'From' => 'Somebody <no-reply@example.com>',
'Subject' => 'Some Subject.');
);

$mime = new Mail_mime($crlf);
$mime->setTXTBody($message);

$body = $mime->get();
$hdrs = $mime->headers($hdrs);

$mail =& Mail::factory('mail');
$mail->send('foobar@example.com', $hdrs, $body);

This will send you an e-mail that looks like this:

Hello

World!
Note by: nobody
Re: comment from rolf.offermanns@*

Note that '\n' is different from "\n".
Note by: rolf.offermanns@gmx.net
Passing '\n' for the crlf parameter in the Mail_mime constructor does not work for me and produces invalid mails.

Omitting the parameter (thus using the default value) works fine!