Skip to main content

EMAIL WITH Pear Mail extension

What is the Pear Mail extension

The Pear mail extension is an easy object oriented approach to sending email with PHP.

It can allow you to send multi-part MIME email without needing to know how things like boundaries and mime types work.


Why

PHP already has the command mail which can send email, and it's already built into the base of PHP.

This method is good, and I have used it many times, but in order
to send complex emails including attachments and protect against mail
header injection attacks, you need to have an in depth understanding of
how email and MIME works.

The Pear Mail extension allows us to do this easily, quickly, and
more importantly, it has been tested thoroughly, probably more so than
any email code that we write.


Installing the Pear mail extension

If you already have pear installed on your server, you can install the pear mail extension by entering the following command.

# pear install mail
# pear install Net_SMTP
# pear install mail_mime

This will put the libraries that we need to use in PHP's include path for your operating system.


Sending your first email

This example shows how to create an email which will display html in
html capable email clients, and text in non capable email clients.

  1. <?
  2.         include('Mail.php');
  3.         include('Mail/mime.php');
  4.  
  5.         // Constructing the email
  6.         $sender = "Leigh <leigh@no_spam.net>";                              // Your name and email address
  7.         $recipient = "Leigh <leigh@no_spam.net>";                           // The Recipients name and email address
  8.         $subject = "Test Email";                                            // Subject for the email
  9.         $text = 'This is a text message.';                                  // Text version of the email
  10.         $html = '<html><body><p>This is a html message</p></body></html>';  // HTML version of the email
  11.         $crlf = "\n";
  12.         $headers = array(
  13.                         'From'          => $sender,
  14.                         'Return-Path'   => $sender,
  15.                         'Subject'       => $subject
  16.                         );
  17.  
  18.         // Creating the Mime message
  19.         $mime = new Mail_mime($crlf);
  20.  
  21.         // Setting the body of the email
  22.         $mime->setTXTBody($text);
  23.         $mime->setHTMLBody($html);
  24.  
  25.         $body = $mime->get();
  26.         $headers = $mime->headers($headers);
  27.  
  28.         // Sending the email
  29.         $mail =& Mail::factory('mail');
  30.         $mail->send($recipient, $headers, $body);
  31. ?>


Adding attachments


Adding one attachment

Adding 1 or many attachments is easy, adding the attachment is done
by calling the addAttachment method, This method can be called multiple
times to add multiple attachemnts.

boolean addAttachment (string $file, string [$c_type = 'application/octet-stream'], string [$name = ], boolean [$isfile = TRUE], string [$encoding = 'base64'])

Variables:

  1. $file: either the variable containing the content of a file, or the path of the file itself
  2. $c_type: content type, meaning the mime type of file eg. text/plain, text/csv, Application/pdf
  3. $name: The name of the file as you want it to appear in the email, this should be unique
  4. $isFile: whether the variable $file is the path to the file, or the content of the file
  5. $encoding: This should usually be left as the default unless you know what you are doing

Attachments can be either stored in a variable, or in a file on the
servers file system. in this first example I will create a small text
file named 'hello text.txt', with the words 'Hello World!' in it.

  1. <?
  2.         include('Mail.php');
  3.         include('Mail/mime.php');
  4.  
  5.         // Constructing the email
  6.         $sender = "Leigh <leigh@no_spam.net>";                              // Who your name and email address
  7.         $recipient = "Leigh <leigh@no_spam.net>";                           // The Recipients name and email address
  8.         $subject = "Test Email";                                            // Subject for the email
  9.         $text = 'This is a text message.';                                  // Text version of the email
  10.         $html = '<html><body><p>This is a html message</p></body></html>';  // HTML version of the email
  11.         $crlf = "\n";
  12.         $headers = array(
  13.                         'From'          => $sender,
  14.                         'Return-Path'   => $sender,
  15.                         'Subject'       => $subject
  16.                         );
  17.  
  18.         // Creating the Mime message
  19.         $mime = new Mail_mime($crlf);
  20.  
  21.         // Setting the body of the email
  22.         $mime->setTXTBody($text);
  23.         $mime->setHTMLBody($html);
  24.  
  25.         // Add an attachment
  26.         $file = "Hello World!";                                      // Content of the file
  27.         $file_name = "Hello text.txt";                               // Name of the Attachment
  28.         $content_type = "text/plain";                                // Content type of the file
  29.         $mime->addAttachment ($file, $content_type, $file_name, 0);  // Add the attachment to the email
  30.  
  31.         $body = $mime->get();
  32.         $headers = $mime->headers($headers);
  33.  
  34.         // Sending the email
  35.         $mail =& Mail::factory('mail');
  36.         $mail->send($recipient, $headers, $body);
  37. ?>


Adding multiple attachments

As in the previous section, adding multiple attachments is as rasy as
calling addAttachment again. In this example I will send an email with
two text attachments.

  1. <?
  2.         include('Mail.php');
  3.         include('Mail/mime.php');
  4.  
  5.         // Constructing the email
  6.         $sender = "Leigh <leigh@no_spam.net>";                              // Who your name and email address
  7.         $recipient = "Leigh <leigh@no_spam.net>";                           // The Recipients name and email address
  8.         $subject = "Test Email";                                            // Subject for the email
  9.         $text = 'This is a text message.';                                  // Text version of the email
  10.         $html = '<html><body><p>This is a html message</p></body></html>';  // HTML version of the email
  11.         $crlf = "\n";
  12.         $headers = array(
  13.                         'From'          => $sender,
  14.                         'Return-Path'   => $sender,
  15.                         'Subject'       => $subject
  16.                         );
  17.  
  18.         // Creating the Mime message
  19.         $mime = new Mail_mime($crlf);
  20.  
  21.         // Setting the body of the email
  22.         $mime->setTXTBody($text);
  23.         $mime->setHTMLBody($html);
  24.  
  25.         // Add an attachment
  26.         $file = "Hello World!";                                      // Content of the file
  27.         $file_name = "Hello text.txt";                               // Name of the Attachment
  28.         $content_type = "text/plain";                                // Content type of the file
  29.         $mime->addAttachment ($file, $content_type, $file_name, 0);  // Add the attachment to the email
  30.  
  31.         // Add a second attachment
  32.         $file = "Hello World! Again :)";                             // Content of the file
  33.         $file_name = "Hello text 2.txt";                             // Name of the Attachment
  34.         $content_type = "text/plain";                                // Content type of the file
  35.         $mime->addAttachment ($file, $content_type, $file_name, 0);  // Add the attachment to the email
  36.  
  37.         $body = $mime->get();
  38.         $headers = $mime->headers($headers);
  39.  
  40.         // Sending the email
  41.         $mail =& Mail::factory('mail');
  42.         $mail->send($recipient, $headers, $body);
  43. ?>


Adding an attachment from the file system

Adding an attachment from the file system is easy, instead of
specifying the contents of the file, we enter the path to the file and
change the $isFile variable. In this example I will attach a PDF called
'example.pdf' which is located in the same folder as this script.

  1. <?
  2.         include('Mail.php');
  3.         include('Mail/mime.php');
  4.  
  5.         // Constructing the email
  6.         $sender = "Leigh <leigh@no_spam.net>";                              // Who your name and email address
  7.         $recipient = "Leigh <leigh@no_spam.net>";                           // The Recipients name and email address
  8.         $subject = "Test Email";                                            // Subject for the email
  9.         $text = 'This is a text message.';                                  // Text version of the email
  10.         $html = '<html><body><p>This is a html message</p></body></html>';  // HTML version of the email
  11.         $crlf = "\n";
  12.         $headers = array(
  13.                         'From'          => $sender,
  14.                         'Return-Path'   => $sender,
  15.                         'Subject'       => $subject
  16.                         );
  17.  
  18.         // Creating the Mime message
  19.         $mime = new Mail_mime($crlf);
  20.  
  21.         // Setting the body of the email
  22.         $mime->setTXTBody($text);
  23.         $mime->setHTMLBody($html);
  24.  
  25.         // Add an attachment
  26.         $file = "example.pdf";                                       // Content of the file
  27.         $file_name = "example.pdf";                                  // Name of the Attachment
  28.         $content_type = "Application/pdf";                           // Content type of the file
  29.         $mime->addAttachment ($file, $content_type, $file_name, 1);  // Add the attachment to the email
  30.  
  31.         $body = $mime->get();
  32.         $headers = $mime->headers($headers);
  33.  
  34.         // Sending the email
  35.         $mail =& Mail::factory('mail');
  36.         $mail->send($recipient, $headers, $body);
  37. ?>

Notice specifically in this example that I kept the file name in the
email the same as the original, although I could just as easily change
it. Additionally the the last variable in the method addAttachment was
1, this is to tell it that $file is the path to the file.


Sending to multiple recipients

The Pear mail package can accept an array of recipients or a list of
comma separated email addresses. In this example we will use an array
called $recipients.

For the best performance sending to multiple recipients we should use SMTP as it only has to connect to the SMTP server once.

  1. <?
  2.         include('Mail.php');
  3.         include('Mail/mime.php');
  4.  
  5.         // Constructing the email
  6.         $sender = "Leigh <leigh@no_spam.net>";                              // Who your name and email address
  7.         $recipients = array();
  8.         $recipients[] = "Leigh account 1 <leigh_1@no_spam.net>";            // Recipient name and email address
  9.         $recipients[] = "Leigh account 2 <leigh_2@no_spam.net>";            // Recipient name and email address
  10.         $subject = "Test Email";                                            // Subject for the email
  11.         $text = 'This is a text message.';                                  // Text version of the email
  12.         $html = '<html><body><p>This is a html message</p></body></html>';  // HTML version of the email
  13.         $crlf = "\n";
  14.         $headers = array(
  15.                         'From'          => $sender,
  16.                         'Return-Path'   => $sender,
  17.                         'Subject'       => $subject
  18.                         );
  19.  
  20.         // Creating the Mime message
  21.         $mime = new Mail_mime($crlf);
  22.  
  23.         // Setting the body of the email
  24.         $mime->setTXTBody($text);
  25.         $mime->setHTMLBody($html);
  26.  
  27.         $body = $mime->get();
  28.         $headers = $mime->headers($headers);
  29.  
  30.         // Sending the email
  31.         $mail =& Mail::factory('mail');
  32.         $mail->send($recipients, $headers, $body);
  33. ?>


Sending using SMTP

This example shows how to send an email using SMTP instead of the
built in PHP mail() function. This is useful if you want to send using a
remote server.

  1. <?
  2.         include('Mail.php');
  3.         include('Mail/mime.php');
  4.  
  5.         // Constructing the email
  6.         $sender = "Leigh <leigh@no_spam.net>";                                  // Your name and email address
  7.         $recipient = "Leigh <leigh@no_spam.net>";                               // The Recipients name and email address
  8.         $subject = "Test Email";                                                // Subject for the email
  9.         $text = 'This is a text message.';                                      // Text version of the email
  10.         $html = '<html><body><p>This is a html message</p></body></html>';      // HTML version of the email
  11.         $crlf = "\n";
  12.         $headers = array(
  13.                         'From'          => $sender,
  14.                         'Return-Path'   => $sender,
  15.                         'Subject'       => $subject
  16.                         );
  17.  
  18.         // Creating the Mime message
  19.         $mime = new Mail_mime($crlf);
  20.  
  21.         // Setting the body of the email
  22.         $mime->setTXTBody($text);
  23.         $mime->setHTMLBody($html);
  24.  
  25.         // Add an attachment
  26.         $file = "Hello World!";
  27.         $file_name = "Hello text.txt";
  28.         $content_type = "text/plain";
  29.         $mime->addAttachment ($file, $content_type, $file_name, 0);
  30.  
  31.         // Set body and headers ready for base mail class
  32.         $body = $mime->get();
  33.         $headers = $mime->headers($headers);
  34.  
  35.         // SMTP params
  36.         $smtp_params["host"] = "smtp.example.com"; // SMTP host
  37.         $smtp_params["port"] = "25";               // SMTP Port (usually 25)
  38.  
  39.         // Sending the email using smtp
  40.         $mail =& Mail::factory("smtp", $smtp_params);
  41.         $result = $mail->send($recipient, $headers, $body);
  42.         if($result === 1)
  43.         {
  44.           echo("Your message has been sent!");
  45.         }
  46.         else
  47.         {
  48.           echo("Your message was not sent: " . $result);
  49.         }
  50. ?>


Sending using authenticated SMTP

This example shows how to send an email using SMTP authentication.
This particular example uses gmail to send. Gmails requirements for
sending via SMTP are SMTP authentication with TLS. Fortunately, when we
use authentication with Pear Mail, the connection is automatically TLS.

The difference between This example, and the previous example just using SMTP is the addition of the following SMTP parameters.

$smtp_params["auth"]   = true;
$smtp_params["username"] = "user@gmail.com";
$smtp_params["password"] = "pass";
  1. <?
  2.         include('Mail.php');
  3.         include('Mail/mime.php');
  4.  
  5.         // Constructing the email
  6.         $sender = "user@gmail.com";                                             // Your email address
  7.         $recipient = "Leigh <leigh@no_spam.net>";                               // The Recipients name and email address
  8.         $subject = "Test Email";                                                // Subject for the email
  9.         $text = 'This is a text message.';                                      // Text version of the email
  10.         $html = '<html><body><p>This is a html message</p></body></html>';      // HTML version of the email
  11.         $crlf = "\n";
  12.         $headers = array(
  13.                         'From'          => $sender,
  14.                         'Return-Path'   => $sender,
  15.                         'Subject'       => $subject
  16.                         );
  17.  
  18.         // Creating the Mime message
  19.         $mime = new Mail_mime($crlf);
  20.  
  21.         // Setting the body of the email
  22.         $mime->setTXTBody($text);
  23.         $mime->setHTMLBody($html);
  24.  
  25.         // Add an attachment
  26.         $file = "Hello World!";
  27.         $file_name = "Hello text.txt";
  28.         $content_type = "text/plain";
  29.         $mime->addAttachment ($file, $content_type, $file_name, 0);
  30.  
  31.         // Set body and headers ready for base mail class
  32.         $body = $mime->get();
  33.         $headers = $mime->headers($headers);
  34.  
  35.         // SMTP authentication params
  36.         $smtp_params["host"]     = "smtp.gmail.com";
  37.         $smtp_params["port"]     = "25";
  38.         $smtp_params["auth"]     = true;
  39.         $smtp_params["username"] = "user@gmail.com";
  40.         $smtp_params["password"] = "pass";
  41.  
  42.         // Sending the email using smtp
  43.         $mail =& Mail::factory("smtp", $smtp_params);
  44.         $result = $mail->send($recipient, $headers, $body);
  45.         if($result === 1)
  46.         {
  47.           echo("Your message has been sent!");
  48.         }
  49.         else
  50.         {
  51.           echo("Your message was not sent: " . $result);
  52.         }
  53. ?>


Security

One of the major concerns of people sending automated emails using
PHP is header injection. Mail header injection is the process of
inserting additional fields into the mail headers such as extra "bcc"
and "to" fields. This can be used by spammers to utilize your server to
send spam and consequently having your server blacklisted by real time
blacklists.

Pear mail automatically sanitizes the headers you pass to it so
that we don't have to worry about it. The following code is what is used
to sanitize the headers.

  1. /**
  2.  * Sanitize an array of mail headers by removing any additional header
  3.  * strings present in a legitimate header's value.  The goal of this
  4.  * filter is to prevent mail injection attacks.
  5.  *
  6.  * @param array $headers The associative array of headers to sanitize.
  7.  *
  8.  * @access private
  9.  */
  10. function _sanitizeHeaders(&$headers)
  11. {
  12.   foreach ($headers as $key => $value) {
  13.   $headers[$key] =
  14.     preg_replace('=((<CR>|<LF>|0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i',
  15.       null, $value);
  16.   }
  17. }

Taken from Mail.php authored by Chuck Hagenbuch Copyright (c) 1997-2003 The PHP Group version 2.02 of the PHP license


Troubleshooting


Pear not up to date

If you get the following:

# pear install mail_mime
pear/Mail_Mime requires PEAR Installer (version >= 1.6.0), installed version is 1.4.9
pear/Mail_mimeDecode requires PEAR Installer (version >= 1.6.0), installed version is 1.4.9
pear/Mail_mimeDecode requires package "pear/Mail_Mime" (version >= 1.4.0, excluded versions: 1.4.

Run the following to upgrade Pear and you will be able to install Mail/Mime:

# pear upgrade-all


Pear Channels protocol not up to date

If you get:

# pear install mail
WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update

Run the following to update:

# pear channel-update pear.php.net


Emails not being sent

View the return value form the line

$mail->send($recipient, $headers, $body);

eg.

echo($mail->send($recipient, $headers, $body));

Ref: http://www.phpmaniac.net/wiki/index.php/Pear_Mail