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.
-
<?
-
include('Mail.php');
-
include('Mail/mime.php');
-
-
// Constructing the email
-
$sender = "Leigh <leigh@no_spam.net>"; // Your name and email address
-
$recipient = "Leigh <leigh@no_spam.net>"; // The Recipients name and email address
-
$subject = "Test Email"; // Subject for the email
-
$text = 'This is a text message.'; // Text version of the email
-
$html = '<html><body><p>This is a html message</p></body></html>'; // HTML version of the email
-
$crlf = "\n";
-
$headers = array(
-
'From' => $sender,
-
'Return-Path' => $sender,
-
'Subject' => $subject
-
);
-
-
// Creating the Mime message
-
$mime = new Mail_mime($crlf);
-
-
// Setting the body of the email
-
$mime->setTXTBody($text);
-
$mime->setHTMLBody($html);
-
-
$body = $mime->get();
-
$headers = $mime->headers($headers);
-
-
// Sending the email
-
$mail =& Mail::factory('mail');
-
$mail->send($recipient, $headers, $body);
-
?>
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:
- $file: either the variable containing the content of a file, or the path of the file itself
- $c_type: content type, meaning the mime type of file eg. text/plain, text/csv, Application/pdf
- $name: The name of the file as you want it to appear in the email, this should be unique
- $isFile: whether the variable $file is the path to the file, or the content of the file
- $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.
-
<?
-
include('Mail.php');
-
include('Mail/mime.php');
-
-
// Constructing the email
-
$sender = "Leigh <leigh@no_spam.net>"; // Who your name and email address
-
$recipient = "Leigh <leigh@no_spam.net>"; // The Recipients name and email address
-
$subject = "Test Email"; // Subject for the email
-
$text = 'This is a text message.'; // Text version of the email
-
$html = '<html><body><p>This is a html message</p></body></html>'; // HTML version of the email
-
$crlf = "\n";
-
$headers = array(
-
'From' => $sender,
-
'Return-Path' => $sender,
-
'Subject' => $subject
-
);
-
-
// Creating the Mime message
-
$mime = new Mail_mime($crlf);
-
-
// Setting the body of the email
-
$mime->setTXTBody($text);
-
$mime->setHTMLBody($html);
-
-
// Add an attachment
-
$file = "Hello World!"; // Content of the file
-
$file_name = "Hello text.txt"; // Name of the Attachment
-
$content_type = "text/plain"; // Content type of the file
-
$mime->addAttachment ($file, $content_type, $file_name, 0); // Add the attachment to the email
-
-
$body = $mime->get();
-
$headers = $mime->headers($headers);
-
-
// Sending the email
-
$mail =& Mail::factory('mail');
-
$mail->send($recipient, $headers, $body);
-
?>
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.
-
<?
-
include('Mail.php');
-
include('Mail/mime.php');
-
-
// Constructing the email
-
$sender = "Leigh <leigh@no_spam.net>"; // Who your name and email address
-
$recipient = "Leigh <leigh@no_spam.net>"; // The Recipients name and email address
-
$subject = "Test Email"; // Subject for the email
-
$text = 'This is a text message.'; // Text version of the email
-
$html = '<html><body><p>This is a html message</p></body></html>'; // HTML version of the email
-
$crlf = "\n";
-
$headers = array(
-
'From' => $sender,
-
'Return-Path' => $sender,
-
'Subject' => $subject
-
);
-
-
// Creating the Mime message
-
$mime = new Mail_mime($crlf);
-
-
// Setting the body of the email
-
$mime->setTXTBody($text);
-
$mime->setHTMLBody($html);
-
-
// Add an attachment
-
$file = "Hello World!"; // Content of the file
-
$file_name = "Hello text.txt"; // Name of the Attachment
-
$content_type = "text/plain"; // Content type of the file
-
$mime->addAttachment ($file, $content_type, $file_name, 0); // Add the attachment to the email
-
-
// Add a second attachment
-
$file = "Hello World! Again :)"; // Content of the file
-
$file_name = "Hello text 2.txt"; // Name of the Attachment
-
$content_type = "text/plain"; // Content type of the file
-
$mime->addAttachment ($file, $content_type, $file_name, 0); // Add the attachment to the email
-
-
$body = $mime->get();
-
$headers = $mime->headers($headers);
-
-
// Sending the email
-
$mail =& Mail::factory('mail');
-
$mail->send($recipient, $headers, $body);
-
?>
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.
-
<?
-
include('Mail.php');
-
include('Mail/mime.php');
-
-
// Constructing the email
-
$sender = "Leigh <leigh@no_spam.net>"; // Who your name and email address
-
$recipient = "Leigh <leigh@no_spam.net>"; // The Recipients name and email address
-
$subject = "Test Email"; // Subject for the email
-
$text = 'This is a text message.'; // Text version of the email
-
$html = '<html><body><p>This is a html message</p></body></html>'; // HTML version of the email
-
$crlf = "\n";
-
$headers = array(
-
'From' => $sender,
-
'Return-Path' => $sender,
-
'Subject' => $subject
-
);
-
-
// Creating the Mime message
-
$mime = new Mail_mime($crlf);
-
-
// Setting the body of the email
-
$mime->setTXTBody($text);
-
$mime->setHTMLBody($html);
-
-
// Add an attachment
-
$file = "example.pdf"; // Content of the file
-
$file_name = "example.pdf"; // Name of the Attachment
-
$content_type = "Application/pdf"; // Content type of the file
-
$mime->addAttachment ($file, $content_type, $file_name, 1); // Add the attachment to the email
-
-
$body = $mime->get();
-
$headers = $mime->headers($headers);
-
-
// Sending the email
-
$mail =& Mail::factory('mail');
-
$mail->send($recipient, $headers, $body);
-
?>
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.
-
<?
-
include('Mail.php');
-
include('Mail/mime.php');
-
-
// Constructing the email
-
$sender = "Leigh <leigh@no_spam.net>"; // Who your name and email address
-
$recipients = array();
-
$recipients[] = "Leigh account 1 <leigh_1@no_spam.net>"; // Recipient name and email address
-
$recipients[] = "Leigh account 2 <leigh_2@no_spam.net>"; // Recipient name and email address
-
$subject = "Test Email"; // Subject for the email
-
$text = 'This is a text message.'; // Text version of the email
-
$html = '<html><body><p>This is a html message</p></body></html>'; // HTML version of the email
-
$crlf = "\n";
-
$headers = array(
-
'From' => $sender,
-
'Return-Path' => $sender,
-
'Subject' => $subject
-
);
-
-
// Creating the Mime message
-
$mime = new Mail_mime($crlf);
-
-
// Setting the body of the email
-
$mime->setTXTBody($text);
-
$mime->setHTMLBody($html);
-
-
$body = $mime->get();
-
$headers = $mime->headers($headers);
-
-
// Sending the email
-
$mail =& Mail::factory('mail');
-
$mail->send($recipients, $headers, $body);
-
?>
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.
-
<?
-
include('Mail.php');
-
include('Mail/mime.php');
-
-
// Constructing the email
-
$sender = "Leigh <leigh@no_spam.net>"; // Your name and email address
-
$recipient = "Leigh <leigh@no_spam.net>"; // The Recipients name and email address
-
$subject = "Test Email"; // Subject for the email
-
$text = 'This is a text message.'; // Text version of the email
-
$html = '<html><body><p>This is a html message</p></body></html>'; // HTML version of the email
-
$crlf = "\n";
-
$headers = array(
-
'From' => $sender,
-
'Return-Path' => $sender,
-
'Subject' => $subject
-
);
-
-
// Creating the Mime message
-
$mime = new Mail_mime($crlf);
-
-
// Setting the body of the email
-
$mime->setTXTBody($text);
-
$mime->setHTMLBody($html);
-
-
// Add an attachment
-
$file = "Hello World!";
-
$file_name = "Hello text.txt";
-
$content_type = "text/plain";
-
$mime->addAttachment ($file, $content_type, $file_name, 0);
-
-
// Set body and headers ready for base mail class
-
$body = $mime->get();
-
$headers = $mime->headers($headers);
-
-
// SMTP params
-
$smtp_params["host"] = "smtp.example.com"; // SMTP host
-
$smtp_params["port"] = "25"; // SMTP Port (usually 25)
-
-
// Sending the email using smtp
-
$mail =& Mail::factory("smtp", $smtp_params);
-
$result = $mail->send($recipient, $headers, $body);
-
if($result === 1)
-
{
-
echo("Your message has been sent!");
-
}
-
else
-
{
-
echo("Your message was not sent: " . $result);
-
}
-
?>
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";
-
<?
-
include('Mail.php');
-
include('Mail/mime.php');
-
-
// Constructing the email
-
$sender = "user@gmail.com"; // Your email address
-
$recipient = "Leigh <leigh@no_spam.net>"; // The Recipients name and email address
-
$subject = "Test Email"; // Subject for the email
-
$text = 'This is a text message.'; // Text version of the email
-
$html = '<html><body><p>This is a html message</p></body></html>'; // HTML version of the email
-
$crlf = "\n";
-
$headers = array(
-
'From' => $sender,
-
'Return-Path' => $sender,
-
'Subject' => $subject
-
);
-
-
// Creating the Mime message
-
$mime = new Mail_mime($crlf);
-
-
// Setting the body of the email
-
$mime->setTXTBody($text);
-
$mime->setHTMLBody($html);
-
-
// Add an attachment
-
$file = "Hello World!";
-
$file_name = "Hello text.txt";
-
$content_type = "text/plain";
-
$mime->addAttachment ($file, $content_type, $file_name, 0);
-
-
// Set body and headers ready for base mail class
-
$body = $mime->get();
-
$headers = $mime->headers($headers);
-
-
// SMTP authentication params
-
$smtp_params["host"] = "smtp.gmail.com";
-
$smtp_params["port"] = "25";
-
$smtp_params["auth"] = true;
-
$smtp_params["username"] = "user@gmail.com";
-
$smtp_params["password"] = "pass";
-
-
// Sending the email using smtp
-
$mail =& Mail::factory("smtp", $smtp_params);
-
$result = $mail->send($recipient, $headers, $body);
-
if($result === 1)
-
{
-
echo("Your message has been sent!");
-
}
-
else
-
{
-
echo("Your message was not sent: " . $result);
-
}
-
?>
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.
-
/**
-
* Sanitize an array of mail headers by removing any additional header
-
* strings present in a legitimate header's value. The goal of this
-
* filter is to prevent mail injection attacks.
-
*
-
* @param array $headers The associative array of headers to sanitize.
-
*
-
* @access private
-
*/
-
function _sanitizeHeaders(&$headers)
-
{
-
foreach ($headers as $key => $value) {
-
$headers[$key] =
-
preg_replace('=((<CR>|<LF>|0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i',
-
null, $value);
-
}
-
}
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));
- Login to post comments