Communicating with website users via email is crucial to the success of any online service. The ability to deliver registration confirmations and newsletters, provide a convenient and relatively secure password recovery tool, and keep clients updated with shipping status reports are just a few of the reasons for incorporating email-based features into your website infrastructure. In this tutorial, I’ll show you how to incorporate email delivery capabilities into your PHP applications via both its native mail command and a great third-party extension called HTML Mime Mail. I’ll conclude the article with a few pointers regarding how to most efficiently carry out bulk email delivery.
The mail() Function
Sending email via a PHP script is easy because PHP offers a native function called mail(). It accepts five parameters, three of which are required and the other two optional. The required parameters include the intended recipient, subject, and message. The optional parameters include additional mail headers and execution options for the mail delivery service. On Unix-based systems this service is by default Sendmail, although you can use other email services such as postfix or qmail, provided that you use sendmail wrappers available to each package. You can specify the location of this service by modifying the configuration directive sendmail_path. On Windows-based systems PHP requires the address of an SMTP server, specified with the SMTP configuration directive. The mail() function looks like this:
boolean mail(string to, string subject, string message [, string addl_headers [, string addl_params]])
Let’s consider a simple example using the mail() function. The following script sends an email to email@example.com:
<?php $to = "firstname.lastname@example.org"; $from = "email@example.com"; $title = "Support subscription confirmation"; $body = <<< emailbody Dear subscriber, This email confirms your purchase of a 30 day email support subscription. Please direct all requests to firstname.lastname@example.org. Thank you, The Example.com support staff emailbody; $success = mail($to,$from,$title,$body, "From:$fromrnReply-To:email@example.com"); ?>
When taking advantage of the addl_headers parameter, keep in mind you’ll need to Note that if you neglect to include the From header, the email will be sent by the Web server daemon owner. When using the Apache Web server, it’s standard practice to use the user nobody or create a new user named apache or www for specifically this purpose. Therefore the above email sender address might look something like firstname.lastname@example.org or email@example.com. Therefore, be sure to set this header value to lessen the possibility of confusion or accidental spam filtering.
The mail() function works great when you want to send just a simple email. However what about sending to multiple recipients? Sending HTML mail? Also, what about sending attachments? While you could use mail(), additional headers, and some additional programming to perform such tasks, there’s another readily available solution that I’d like to introduce.
HTML Mime Mail
HTML Mime Mail is a very useful PHP class created and maintained by Richard Heyes (http://www.phpguru.org/). Available for free download and use under the BSD license, it’s a fantastic class for sending MIME-based email. Offering an intuitive OOP syntax for managing email submissions, it’s capable of executing all of the email-specific tasks discussed thus far, in addition to features such as handling attachments, sending plain-text emails, and sending HTML emails with embedded images. In this article I’ll show you how to take advantage of this great tool.
Installing Mime Mail
HTML Mime Mail is available for download from Richard Heyes’ website:
Uncompress the file to a location preferably accessible by PHP’s include_path setting. If this setting isn’t available to you (for instance, you’re using a shared server ISP), then uncompress it to a convenient location. Then include the class in your script using the REQUIRE_ONCE statement. In the following example I’ve placed the HTML Mime Mail directory in the same directory as my script:
For this tutorial I’m using HTML Mime Mail version 2.5.1, which was rewritten for PHP 5. Take note that if you’re still running PHP 4, you’ll need to use an earlier version of the class.
Sending an Email
HTML Mime Mail’s object-oriented interface makes sending email quite intuitive. In this first example I’ll assign the sender address, subject, body text, and finally submit the message for delivery:
<?php require_once("htmlMimeMail5/htmlMimeMail5.php"); // Instantiate a new HTML Mime Mail object $mail = new htmlMimeMail5(); // Set the sender address $mail->setFrom("firstname.lastname@example.org"); // Set the reply-to address $mail->setReturnPath("email@example.com"); // Set the mail subject $mail->setSubject("Test HTML Mime Mail"); // Set the mail body text $mail->setText("This is the body of the test email."); // Send the email! $mail->send(array("firstname.lastname@example.org")); ?>
As you can see, HTML Mime Mail offers a much more convenient means for creating and sending email messages than PHP’s native interface. But this is just a sampling of this useful class’s capabilities. Read on to learn more.
Sending to Multiple Recipients
In the last example, you may have noticed the send() method requires that the recipient address is presented as an array element. This is because send() allows for emails to be sent to multiple users by simply appending new elements to the array. The following example sends an email to two users, namely email@example.com and firstname.lastname@example.org:
// Send the email to email@example.com $result = $mail->send(array('firstname.lastname@example.org', 'email@example.com'));
You can also specify other recipients in the same fashion using the setCc() and setBc() methods.
Sending an Attachment
The question of how to send attachments using PHP’s mail() function comes up quite frequently in newsgroups. I’m happy to forego the gory details of how it’s accomplished in this tutorial, because the HTML Mime Mail class resolves the problem quite easily. In the following example I’ll send an email with an attachment titled htmlmimemail.doc to firstname.lastname@example.org:
<?php require_once("htmlMimeMail5/htmlMimeMail5.php"); // Instantiate a new HTML Mime Mail object $mail = new htmlMimeMail5(); // Set the From and Reply-To headers $mail->setFrom("Jason <email@example.com>"); $mail->setReturnPath("firstname.lastname@example.org"); // Set the Subject $mail->setSubject("Test with attached email"); // Set the body $mail->setText("Please find the new tutorial attached. Thank you!"); // Retrieve a file for attachment $attachment = new fileAttachment("htmlmimemail.doc", "application/vnd.ms-word"); // Attach the file, assigning it a name and a corresponding Mime-type. $mail->addAttachment($attachment); // Send the email to email@example.com $result = $mail->send(array('firstname.lastname@example.org')); ?>
Sending out HTML formatted email
Personally, I think receiving HTML-formatted email is akin to scratching one’s nails on the blackboard. There’s simply no reason for it. However there has been such an ongoing interest in learning how to do so programmatically that I don’t think this tutorial would be complete without some discussion of the matter. Like attachments, sending HTML-formatted email with HTML Mime Mail is amazingly easy. The following example sends email@example.com an HTML-formatted email with a gray background and a GIF image named advertisement.gif. Note that the second (optional) parameter of the setHTML() method specifies the location of the images that should be embedded in the email. You also have the option of pointing the images to an online location, however keep in mind that some email clients (Squirrelmail for example) will not render these images for reasons of security.
<?php require_once("htmlMimeMail5/htmlMimeMail5.php"); // Instantiate a new HTML Mime Mail object $mail = new htmlMimeMail5(); // Set the From and Reply-To headers $mail->setFrom("Jason <firstname.lastname@example.org>"); $mail->setReturnPath("email@example.com"); // Set the Subject $mail->setSubject("HTML formatted email"); $html = " <body bgcolor='#808080'> <img src='advertisement.gif' alt='Buy my book!'> </body>"; // Create the HTML email $mail->setHTML($html, "/home/apache/newsletter/images//"); // Send the email to firstname.lastname@example.org $result = $mail->send(array('email@example.com')); ?>
Sending out Bulk Email
Web-based PHP scripts aren’t designed to run for long periods of time (the default execution time is 30 seconds), and this presents a problem if you need to send a weekly newsletter to a large number of recipients. Therefore you’ll want to consider alternative solutions for such purposes. These solutions not only facilitate subscriber management, but also support a wide variety of additional useful features such as auto-responses, web-based subscription/unsubscription, and web-based newsletter administration. As you might imagine, several open source software packages are available. I’ll highlight two of the most popular packages here:
- Mailman (http://www.gnu.org/software/mailman/)
- Majordomo (http://www.greatcircle.com/majordomo/)
While these open source solutions are indeed powerful, both serve primary roles as mailing list administrators, and accordingly are lacking in a few features one might expect of a newsletter-specific application. For instance, scheduled mailings, response tracking, and custom HTML templates are just a few features that could greatly enhance the utility of this service. That said, if you have a budget available for purchasing third-party services, I suggest taking some time to evaluate a few commercial offerings. I’ll highlight some of the more promising services here:
- MyEmma (http://www.myemma.com)
- Microsoft ListBuilder (http://www.microsoft.com)
- Groundspring.org (http://www.groundspring.org/)
Alternatively you could take advantage of PHP’s command-line interface (CLI), enabled by default as of version 4.3.0. Using the CLI, you can create scripts that execute directly from the command-line, or on a scheduled basis using a daemon such as CRON. PHP CLI scripts don’t lack any of the features available to you when building Web applications, and have the additional advantage of being able to execute for a long period of time.
Communicating via email is a wonderfully effective and cheap means for enhancing your website’s capabilities and keeping users updated regarding your organization’s latest offerings. Using PHP and the great HTML Mime Mail class, doing so programmatically has never been easier. If you found this tutorial useful, I welcome you to email me with your comments and questions at wj AT wjgilmore.com. Thank you!
About the Author
W. Jason Gilmore (http://www.wjgilmore.com/) is the Open Source Editor for Apress (http://www.apress.com/). He’s the author of Beginning PHP 5 and MySQL: Novice to Professional (Apress, 2004. 748pp.). His work has been featured within many of the computing industry’s leading publications, including Linux Magazine, O’Reillynet, Devshed, Zend.com, and Webreview.