Home > PHP > Sending eMails via PHP using the mail() function

Sending eMails via PHP using the mail() function

Looking up the official PHP guide, we can see how to use the mail function, I’ll try and explain them here and give a few examples of how to add additional headers. Let’s move along the function header from left to right, the mail() function is declared as:

bool mail  ( string $to  , string $subject  , string $message  [, string $additional_headers  [, string $additional_parameters  ]] )

The first thing we see is that the mail function returns a bool, or boolean. So every time this function is run it will either tell you whether it was successfully sent or not. Now I want to be careful here, just because the message has been sent does not mean that the message ever made it to the users mailbox. The message could bounce back because you entered the wrong address, it was flagged as spam, the email address doesn’t exist anymore, etc… This is kind of like mail with the post office, just like when you put a stamp on a letter and mail it, you can say that the message was sent, but it doesn’t mean the message will ever be received.

$to = "noreply@brangle.com";
$subject = 'Test Message with the Mail() command';
$message = "Lorem ipsum dolor sit amet, consectetur
     adipisicing elit, sed do eiusmod tempor incididunt ut labore
     et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud";

if (mail($to, $subject, $message)) {
   echo 'Your message was sent!';
} else {
   echo 'Your message failed to send!';
}

If you were to execute the above script it would send an email to noreply@brangle.com and everything would be honkey dorey. But now what if we wanted to improve on it and add some HTML, then we’re going to need the modify the headers of the message. It’s also important to note, that I am using only \n and not \r\n this is for a variety of reasons, particularly GMail.

Using the $message variable

$headers  = 'MIME-Version: 1.0' . "\n";
$headers .= 'Content-type: text/html; charset=UTF-8' . "\n";
$headers .= 'To: John Doe <john@example.com>, Jane Doe <jane.doe@example.com>' . "\n";
$headers .= 'Cc: babydoe@example.com' . "\n";
$headers .= 'Bcc: brangle-archive@example.com' . "\n";
$headers .= 'From: Brangle.com Webmaster ' . "\n";
$headers .= 'Reply-To: webmaster@example.com' . "\n";
$headers .= 'Return-Path: webmaster@example.com' . "\n";
$headers .= 'X-Mailer: PHP/' . phpversion() ."\n";

So I entered a whole bunch of headers above, but they’re 4 headers which you should always use, even if your only sending text, and they are: Content-Type, From, Reply-To, Return-Path header. If you want to send your email in HTML then you absolutely need to include the Content-Type header. Now unless your sending email in some Asian languages then UTF-8 should always work for you, but please correct me in the comments if I’m wrong. If you forget to send the envelope from address in the headers then the PHP mail() function will automatically do this for you without you even knowing, the problem is what if it grabs the wrong email address, or even a non-existant email address?!? That’s why we want to explicitly define it. You can check your PHP.ini file to see who your email is defaulted from and change it there if you’d like, but if you’re like me and don’t have access to this file then the easiest way is to create the following php file…

<? phpinfo(); >

Now visit this file on your webserver and search for sendmail_from this will tell you who all your email is "sent from." Now continuing on, you can easily remove any line from the php headers that I outlined above without any PHP parsing errors.

if you want to send my message with a high priority, then just add the following headers:

$headers .= 'X-Priority: 1 (Highest)' . '"\n";
$headers .= 'X-MSMail-Priority: High\n' . '"\n";
$headers .= 'Importance: High' . '"\n";

For more advanced users…
I think you should always log all outgoing emails, either to a text file or to your database, now these emails are just for archival purposes and can probably be flushed (deleted) within 90 to 365 days, or whenever you deem necessary. When you generate an email to send, you should log the email id number and include it in the email message that way if a user emails you back about an email they received you can go back and look at what exactly you sent.

If you have a flaky email server, I would recommend changing your web host, I have used DreamHost for several years and have never had a problem with them. But now for the rest of you out there who refuse to change your webhost, I can think of only one recommendation. But since this is a tutorial on how to use the mail() function, I’m only going to provide some psuedocode. If there’s enough request, I could develop this into a full fledged tutorial, but until then…

$i = 0;
while (!mail($to, $subject, $message, $headers)) {
   sleep(10); //this will sleep for ten seconds
   $i++;  
   if ($i >= 3) {
      //perform a sql insert with the following values $to, $subject, $message, $headers, time()
      //This will allow you to save the email in your database where you can create a cron job
      //to execute a query ever hour or so until your mail server is back up, and when it is sort
      //thru all those emails and send them out and flush them from the database.
   }
}
echo 'You should receive your email within 24 hours';

One important thing to remember for all webmasters to note, if you have a flaky mail server and you feel like you have a reputable hosting provider then the issue may be the amount of emails that you are allowed to send daily. Many hosting providers put a cap on the number of mail() function calls you can make in a day, you should definitely look into this.

Categories: PHP Tags:
  1. Neill
    August 25th, 2009 at 07:28 | #1

    Can you explain in more detail why you are breaking the spec and using “\n” only instead of “\r\n”? I have recently been seeing errors in the headers sent from my site through GoDaddy (some of the headers are not correctly recognised) which don’t appear for emails that go through to yahoo and this is a very recent change. Is the “\r\n” the cause? If so what errors can you introduce by not following the standard?

    Thanks

    Neill

  1. September 30th, 2021 at 16:50 | #1
  2. December 30th, 2021 at 16:28 | #2