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(array('eol' => $crlf));

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

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

$mail =& Mail::factory('mail');
$mail->send('postmaster@localhost'$hdrs$body);

?>
encode a mail (Previous) Mail_MimeDecode (Next)
Last updated: Tue, 21 Oct 2014 — Download Documentation
Do you think that something on this page is wrong? Please file a bug report or add a note.
View this page in:

User Notes:

Note by: magesh@armaven.com
Hi,

in both case - with and with out attachment, the mail is sent with out sent date and time detail. in our test mail received in outlook. instead of 'sent:date &time' , it is showing 'sent: none' in the mail header.

please help me to resolve this.

regards,
magesh
Note by: fredrik@krafftit.se
SMTP And UTF-8

This is a addition to SMTP.

I had problems using UTF-8 even though the headers was set to UTF-8.

Insted of changing //include/pear/Mail/mime.php

'html_charset' => 'UTF-8',
'text_charset' => 'UTF-8',
'head_charset' => 'UTF-8'

I could add these

$mimeparams['text_encoding']="8bit";
$mimeparams['text_charset']="UTF-8";
$mimeparams['html_charset']="UTF-8";
$mimeparams['head_charset']="UTF-8";

See example below.



// Require Pear Mail Packages
require_once ("Mail.php");
require_once ("Mail/mime.php");

$text = "test";
$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>....</title>
</head>
<body>
<p>...</p>
</body>
</html>';

$headers["From"] = '....';
$headers["To"] = "...";
$headers["Subject"] = "...";
$headers["Content-Type"] = 'text/html; charset=UTF-8';
$headers["Content-Transfer-Encoding"]= "8bit";


$mime = new Mail_mime;
$mime->setTXTBody($text);
$mime->setHTMLBody($html_message);
$mimeparams=array();


// It refused to change to UTF-8 even if the header was set to this, after adding the following lines it worked.

$mimeparams['text_encoding']="8bit";
$mimeparams['text_charset']="UTF-8";
$mimeparams['html_charset']="UTF-8";
$mimeparams['head_charset']="UTF-8";

$mimeparams["debug"] = "True";

$body = $mime->get($mimeparams);
$headers = $mime->headers($headers);
$page_content = "Mail now.";


// SMTP server name, port, user/passwd
$smtpinfo["host"] = "...";
$smtpinfo["port"] = "26";
$smtpinfo["auth"] = true;
$smtpinfo["username"] = "...";
$smtpinfo["password"] = "...";
$smtpinfo["debug"] = "True";


// Create the mail object using the Mail::factory method
$mail=& Mail::factory("smtp", $smtpinfo);

$mail->send($to, $headers, $body);
Note by: digit6@gmail.com
New PEAR user here and I would like to mention that simply

pear install Mime_mail

did NOT install everything required. I had to also run

pear install Mail

Otherwise, <pear_dir>/Mail.php did not exist and neither did <pear_dir>/Mail/mail.php

Which obviously cause my include commands to fail.


I would also like to mention that there is something wrong with the way $mime->headers() it totally mangles my "From" variable. You see, I like to include a Company name along with the email address so my from string looked like this:

'From' => "\"Company Name\"<user@domain.com>",

The headers() function would run and then if I output the 'From' value from the array I would get this:

\"Company" Name[\n]<user@domain.com>

(or something along those lines)

First of all, I have no idea what it is doing with the quotes or why it would move one and leave the other unescaped as it should be.

When this happens the email is NOT delivered. Its just lost in forever.

I have to, after I call headers(), execute this line to fix what it broke:

$hdrs['From'] = $from;

The quotes are required when the name preceeding the email address has a space in it as far as I know. So why is this broken?
Note by: Charlie Brown
Fails as-is. Change this line:
$hdrs = $mime->txtHeaders($hdrs);
to:
$hdrs = $mime->headers($hdrs);

The former returns a string which causes send() to fail as it expects an array.
Note by: jepe@ck.dk
if you change to SMTP (and poss sendmail) mail method keep in mind that
$hdrs=$mime->txtHeaders($hdrs); will break the code.

use

$hdrs=$mime->headers($hdrs); instead

took me a while to figure that one out :)
Note by: paul@sp-tech.co.uk
When using 'mail' as the sending method (as in this example) the second parameter of Mail::factory() becomes the fifth parameter of PHP mail().

$mail =& Mail::factory('mail','-f you@yourdomain.com');

This will set the email envelope return-path to you@yourdomain.com so bounced emails go somewhere useful.

If this is not set the return-path will probably be something like 'nobody@your-server-name'.
Note by: Paul
To set the envelope Reply-to header correctly (so that bounced emails arrive where you expect them, make these changes to the example:

<?php
include('Mail.php');
include(
'Mail/mime.php');
include(
'Mail/mail.php');     // adds the enhanced send function

$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','-f you@yourdomain.com');   // add the fifth parameter for the PHP mail() function
$mail->send('postmaster@localhost'$hdrs$body);
?>


We are including 'Mail/mail.php' which contains the updated version of the send function (the one in Mail.php is deprecated). This allows the fifth parameter for the PHP mail() function to be included as a parameter to Mail::factory
Note by: e5kim0@hotmail.com
I had a problem... I have this script running just perfectly in may windows o.s. When I tried to deploy it to my centos server the script fails when i try to $mime = new Mail_mime($crlf); and I don't know how to make it work. I've already installed the pear package and still does not work! Any ideas?? thanks
Note by: e5kim0@hotmail.com
Hi there. This is my problem... Whenever I try to use this test in a centos it does not function well when he tries "$mime = new Mail_mime($crlf);".... In a windos runnig xampp it does work but i don't understand why does he fails in centos??!! Can anyone help me....? Plz
Note by: user@example.com
This example requires Pear package Mail also to be installed and php include_path set correctly.
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!