Advanced email in PHP I wish I could remember the very first email message I ever sent. Unfortunately, the truth is that I've come to take email for granted; for instance, I easily send more email messages than I make phone calls. Because the novelty has long since worn off, the memory of that first email is as lost to me as my first phone call; but I doubt my sense of wonder was any less complete at the time. To someone who has never seen email in action before, that first message can be magical. In this article, I'll try to recapture some of that magic for those of you who have never created a Web site that sends email messages. We'll see how the PHP server-side scripting language may be set up to send email, and explore how to send complex message types such as HTML email or emails with file attachments. Note: This article was written back when things like HTML email and file attachments were a lot more difficult to do in PHP than they are today. Before you dive into the from-scratch solutions presented in this article, you might consider investigating PHPMailer, a free library for PHP that provides all of these features with minimal hair-pulling and gnashing of teeth.
PHP Email Setup Before we can send email with PHP, we need to set it up to do so, just as you need to set up your email program before it can send messages. Configuration for sending email in PHP is done with the php.ini file, so open up your Web server's php.ini in whichever editor you normally use. If you don't run your own server, but instead have a PHP-equipped Web host, you can safely assume that everything in this section has been done for you, and skip ahead. In the section entitled [mail function] in the php.ini file, you'll find three settings: SMTP, sendmail_from, and sendmail_path. If your server runs on a Windows machine, you'll want to set the SMTP option to point to your SMTP server (or your ISP's SMTP server, if you're setting up PHP on your home machine). If instead you're setting up PHP on a Linux (or other Unix-based OS) server, you'll want to set the sendmail_path option to point to the sendmail program on your server, passing it the -t option. You can use the SMTP option in Linux instead if you don't have sendmail set up. In either case, you'll want to set the sendmail_from option to your email address, or whichever address you'd like to appear as the default 'from' address for emails sent from PHP scripts. Here's how the section might look on a typical Windows server, or on a Linux server without sendmail: [mail function] ; Setup for Windows systems SMTP = smtp.my.isp.net sendmail_from =
[email protected]
And here's how it might look on a Linux server with sendmail: [mail function] ; Setup for Linux systems sendmail_path = /usr/sbin/sendmail -t sendmail_from =
[email protected]
With those settings in place, restart your Web server and you're ready to go!
Sending Plain Email It doesn't come much easier than the procedure to send plain text email in PHP. In fact, you can do it in just one line in a PHP script:
The above line would send an email message to
[email protected] with 'Subject' as the subject line and 'Your message here.' as the message body. As you can see, PHP's mail function makes sending email exceedingly simple, but there are a few advanced tricks we can use to get more out of this simple function. First of all, if the mail system you configured in your php.ini file rejects a message you try to send (for example, if the 'to' address is not a valid email address), this function will display an error message in the user's browser. Like most PHP functions, however, error messages may be suppressed by preceding the function name with an @ symbol. Combine this with the fact that the mail function returns either true or false depending on whether the email was accepted by the mail sending system, and you have a formula to send email with appropriate error checking: Mail sent successfully.'); } else { echo('
Mail could not be sent.
'); } ?>
Note that just because an email message could be sent doesn't guarantee it will arrive at its destination. An email address can be valid (i.e. correctly formed) but not actually exist. For instance, you can successfully send a message to
[email protected] -- that is, the mail function will return true -- but the message will bounce because no such user exists. PHP provides no built-in means of detecting when this happens. When you want to send a message to multiple recipients, you can just list their email addresses one after another, separated by commas, in the first parameter. For example:
That about covers the basics of the mail function; now let's really get fancy and explore mail headers and what we can do with them!
HTML Email and Other Headers So now you can send email from your PHP scripts. How exciting! Although I'm sure you're already drunk with power, would you like to know how to send HTML email too? Of course you would! To understand HTML email, first you need to understand mail headers. Any given email message is made up of two parts: the headers and the message body. Here's how a simple message looks when your email program fetches it from your ISP:
Return-Path: <
[email protected]> Delivered-To:
[email protected] Received: ...several lines like this... From: Sender <
[email protected]> To: You
Subject: A Simple Message Date: Mon, 11 Feb 2002 16:08:19 -0500 Organization: Sender's Company X-Mailer: Microsoft Outlook, Build 10.0.2616 Hi there! Is this thing on?
Everything up to the blank line makes up the headers for this message. In actual fact, most email messages will have many more header lines than this; however, to keep our focus I trimmed this example down to the bare essentials. As you can see, every line of the headers begins with the name of the header (From:, To:, Subject:, Date:, etc.), followed by some value. Most headers are standardized, and have a specific meaning, either to your mail program or to the mail servers that were responsible for getting the message to you. Nonstandard headers exist as well, and they all begin with X- (e.g. X-Mailer:, a non-standard header, often appears to indicate the program that was used to send the message). NOTE: If a header's value needs more than one line, additional lines should begin with a space. We'll see an example of this in the next section. As soon as your mail program gets to a blank line, it knows the headers are over and the rest of the email is the message body, which it should display. In this case, the message body is the last line above. PHP's mail function lets you specify your own headers, which it adds to those it generates automatically to get your message where it needs to go. For example, the following call to the mail function will add an X-Mailer: header to the outgoing message, identifying PHP 4.x as the sending program:
This optional fourth parameter is most often used to specify a 'from' address other than the default specified in php.ini. Let's add a From: header to do just that:
Note that since headers each appear on a single line, we must separate our two headers with a new line character (\n), which means I need to use double quotes around the header string (single quoted strings don't recognize special character codes like \n). Additional headers also let you assign names to email addresses by specifying them in the format name <email>. Here's our example again, but this time with names "The Sender" and "The Receiver" attached to the relevant addresses:
?>
"To: The Receiver \n" . "From: The Sender <[email protected]>\n" . "X-Mailer: PHP 4.x");
Notice that to do this, we've had to specify the To: header manually, since the first parameter of PHP's mail function doesn't support this more advanced address format. We must still list all the recipients of the message as bare email addresses in the first parameter, however. The cc: and Bcc: headers provide the ability to send carbon copies and blind carbon copies of a message as well: \n" . "From: The Sender <[email protected]>\n" . "cc: Interested <[email protected]>\n" . "Bcc: Me Too <[email protected]>\n" . "X-Mailer: PHP 4.x"); ?>
See how the email addresses of all recipients, be they actual addressees (To), carbon copies (Cc), or blind carbon copies (Bcc) are listed in the first parameter? This isn't documented anywhere, but in my testing I've found that it's absolutely vital if you want the message to get to everyone it's supposed to, especially on Windows servers where PHP's mail function is especially sensitive. BUG ALERT: There are two apparent bugs in the PHP mail function, which I've observed as recently as PHP 4.1.0, that you must be aware of. First, the Cc: header must be typed 'cc:' (as above) or 'CC:', that is, in either all-caps or low-caps. The mixed case version (Cc:) should work, but it doesn't. Secondly, on Windows servers, the Bcc: header does not work as it should. Bcc: recipients do get a copy of the message, but the Bcc: headers are not stripped out of the message during sending, so recipients can see the Bcc: receivers by looking at those lines in the headers. What does all this have to do with HTML email, you ask? Well, a few special headers will cause the message body to be interpreted as HTML by email clients that support it: Your message here.