How to Send Emails in PHP?

We see numerous requests for guides on sending emails with some popular frameworks and libraries using an SMTP server, so we are launching a series of “how to” posts aimed at helping you painlessly configure the mail function in your application.

Today we are starting with PHP, one of the most popular web development languages.

PHP Built-in Mail Function ()

There are two basic ways of sending emails with PHP: a built-in mail function and external mail packages.

PHP’s built-in mail function () is very simple, but it provides limited functionality for sending emails. You won’t be able to add attachments to your email, and building a beautiful HTML template with embedded images will be a tricky task as well. 

The other side of the PHP mail function () is that the email is sent from your web server, which may cause issues with deliverability due to security concerns such as suspicion of spam and blacklisting. The best way to overcome this problem is sending messages via an SMTP server, however, this functionality is limited as well. PHP mail() does not usually allow you to use the external SMTP server and it does not support SMTP authentication.

Here’s what you can do with PHP’s built-in mail function(): 

  • create simple HTML/text messages without attachments and images
  • send emails via localhost and Xmapp 
  • include several recipients with “$to” parameter. 

It is suitable for simple, mostly text-based notifications in your local environment. If you need to communicate with your app’s users, it is better to install an external mailer package.

If you are still committed to the PHP built-in mail function() and are ready to accept the challenge, let’s take a look at the basic code and its main parameters. 

Syntax and Parameters

The PHP mail syntax is pretty simple:

<?php
mail($to_email_address,$subject,$message,[$headers],[$parameters]);
?>

It uses the following parameters: 

  • “$to” = your message recipient(s). The email address format may be user@example.com or User <user@example.com>. In general, it needs to comply with RFC 2822.
  • “$subject” = your message’s subject
  • “$message” = the body of your message. Lines should be separated with a CRLF (\r\n). Each line should not exceed 70 characters.
  • “[$headers]” = additional recipients of your message, which can be included in CC or BCC.  Headers are optional, except for the “from” header: it must be specified, otherwise, you will receive an error message like Warning: mail(): “sendmail_from” not set in php.ini or custom “From:” header missing.

For more details and additional parameters, refer to the PHP documentation.  

Sending HTML Email Using PHP mail() function

The body of the message can be written in HTML. However, as we’ve mentioned above, it should be simple. In the PHP mail function(), the HTML part will look like this:

$message = '
<html>
<head>
  <title>Review Request Reminder</title>
</head>
<body>
  <p>Here are the cases requiring your review in December:</p>
  <table>
    <tr>
      <th>Case title</th><th>Category</th><th>Status</th><th>Due date</th>
    </tr>
    <tr>
      <td>Case 1</td><td>Development</td><td>pending</td><td>Dec-20</td>
    </tr>
    <tr>
      <td>Case 1</td><td>DevOps</td><td>pending</td><td>Dec-21</td>
    </tr>
  </table>
</body>
</html>
';

It’s important to remember that to send HTML mail, you need to set the Content-type header:

$headers[] = 'MIME-Version: 1.0';
$headers[] = 'Content-type: text/html; charset=iso-8859-1';

Simple Transmission Protocol (SMTP)

Where do I specify the SMTP settings? This is a fair question. Go to the PHP installation folder and configure them in the “php.ini” file. But this will only work for localhost or Xmapp like solutions because as we have already mentioned,  PHP mail function does not support SMTP authentication and doesn’t allow sending messages via external servers. 

There are some other, rather haphazard options but we won’t promote them here. Alternatively, we recommend using external PHP mail packages for sending emails via an external SMTP server.

Sending Multiple Emails

To send your message to multiple recipients, specify their email addresses in “$to” =  parameter separating them with comma(-s).  It’s the only suitable method with a native mail() function. If you need to send a large volume of messages in a loop, try an external mailing package. In the official PHP documentation,  PEAR::Mail is recommended. 

PHP Mailing Packages

As we have already mentioned, the native PHP mail() function is not designed for creating email templates and sending a large volume of emails. There are several popular mail packages, and we are going to review them below.

Pear Mail

Pear Mail is a class that provides multiple interfaces for sending emails (which is stated in their documentation). 

Here is what you can do with Pear Mail: 

  • create complex HTML/text messages with attachments and inlined images (with Mail_Mime class)
  • send emails via PHP’s built-in mail() function, a sendmail program, or SMTP server
  • send multiple emails from a queue (with Mail_Queue class).

Pear documentation looks a bit complicated but it’s still informative, and you can find several tutorials. To be able to compare several mail packages, let’s review code for sending a standard booking confirmation email. It will contain HTML and text parts, a single attachment, and will be sent via an authenticated SMTP server. 

For email experiments, we will use Mailtrap, a fake SMTP server. It imitates a real SMTP server and traps your test email in the virtual inboxes. This way, your email samples will never go to the inboxes of the real customers. 

require_once './vendor/autoload.php';
$from = 'Your Hotel <confirmation@hotel.com>';
$to = 'Me <me@gmail.com>';
$subject = 'Thanks for choosing Our Hotel!';
 
$headers = ['From' => $from,'To' => $to, 'Subject' => $subject];
 
// include text and HTML versions 
$text = 'Hi there, we are happy to confirm your booking. Please check the document in the attachment.';
$html = 'Hi there, we are happy to <br>confirm your booking.</br> Please check the document in the attachment.';
 
//add  attachment
$file = '/confirmations/yourbooking.pdf';
 
$mime = new Mail_mime();
$mime->setTXTBody($text);
$mime->setHTMLBody($html);
$mime->addAttachment($file, 'text/plain');
 
$body = $mime->get();
$headers = $mime->headers($headers);
 
$host = 'smtp.mailtrap.io';
$username = '1a2b3c4g5f6g7e'; // generated by Mailtrap
$password = '1a2b3c4g5f6g7e'; // generated by Mailtrap
$port = '2525';
 
$smtp = Mail::factory('smtp', [
  'host' => $host,
  'auth' => true,
  'username' => $username,
  'password' => $password,
  'port' => $port
]);
 
$mail = $smtp->send($to, $headers, $body);
 
if (PEAR::isError($mail)) {
    echo('<p>' . $mail->getMessage() . '</p>');
} else {
    echo('<p>Message successfully sent!</p>');
}

Swift Mailer

Swift Mailer is another popular package for sending emails in PHP. It is feature-rich, well covered by documentation, and pretty straightforward in use. Mailers in both Laravel and Symfony are based on it, and it is an extra argument for using Swift Mailer.

Here is what you can do with Swift Mailer:

  • create complex HTML/multipart templates 
  • add attachments and embed images
  • send emails via authenticated SMTP, sendmail, Postfix, or your own transport
  • use additional plugins.

Besides that, Swift Mailer offers enhanced security and handles large attachments and images with low memory usage.  

For more details, refer to the “How to Send Emails in Symfony with Examples” post. Below we will demonstrate a simple example of the same sending booking confirmation we used above. 

<?php
require_once './vendor/autoload.php';
 try {
    // Create the SMTP transport
    $transport = (new Swift_SmtpTransport('smtp.mailtrap.io', 2525))
        ->setUsername('1a2b3c4d5e6f7g')
        ->setPassword('1a2b3c4d5e6f7g');

    $mailer = new Swift_Mailer($transport);
 
    // Create a message
    $message = new Swift_Message();

    $message->setSubject('Thanks for choosing Our Hotel!');
    $message->setFrom(['confirmation@hotel.com' => 'Your Hotel']); 
    $message->addTo('me@gmail.com','Me');
    // Add attachment
   $attachment = Swift_Attachment::fromPath('./confirmations/yourbooking.pdf');
    $message->attach($attachment);
 
    // Set the plain-text part
    $message->setBody('Hi there, we are happy to confirm your booking. Please check the document in the attachment.');
     // Set the HTML part
    $message->addPart('Hi there, we are happy to <br>confirm your booking.</br> Please check the document in the attachment.', 'text/html');
     // Send the message
    $result = $mailer->send($message);
} catch (Exception $e) {
  echo $e->getMessage();
}

PHPMailer

And finally, PHPMailer, which is the classic and the most popular email sending library for PHP. It deserves a separate article and a tutorial. You will find it here.

Here is what you can do with PHPMailer:

  • create complex HTML/multipart templates
  • add attachments and embedded images
  • send emails via authenticated SMTP. 

PHPMailer is protected against header injection attacks and automatically validates emails. 

Now let’s send our booking confirmation with PHPMailer:

<?php
// Start with PHPMailer class
use PHPMailer\PHPMailer\PHPMailer;
require_once './vendor/autoload.php';
// create a new object
$mail = new PHPMailer();
// configure an SMTP
$mail->isSMTP();
$mail->Host = 'smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = '1a2b3c4d5e6f7g';
$mail->Password = '1a2b3c4d5e6f7g’;
$mail->SMTPSecure = 'tls';
$mail->Port = 2525;

$mail->setFrom('confirmation@hotel.com', 'Your Hotel');
$mail->addAddress('me@gmail.com', 'Me');
$mail->Subject = 'Thanks for choosing Our Hotel!';
// Set HTML 
$mail->isHTML(TRUE);
$mail->Body = '<html>Hi there, we are happy to <br>confirm your booking.</br> Please check the document in the attachment.</html>';
$mail->AltBody = 'Hi there, we are happy to confirm your booking. Please check the document in the attachment.';
// add attachment
$mail->addAttachment('//confirmations/yourbooking.pdf', 'yourbooking.pdf');
// send the message
if(!$mail->send()){
    echo 'Message could not be sent.';
    echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
    echo 'Message has been sent';
}

What Else Should you Know About PHP Mail Sending Options?

In this article, we have described the basic PHP email sending principles, syntax, and parameters. Moreover, we have reviewed the main ways of sending emails with PHP: its built-in mail function and the most popular external mail packages. PHPMailer and Swift Mailer are standard libraries for PHP email sending today, and PEAR Mail is still widely used. 

Undoubtedly, external libraries offer much more advanced solutions, like SMTP authentication support and a wide set of HTML related features. However, PHP mail function() can still be an option if you are sending plain text notification via localhost. 

Also, you can find several additional packages to supplement your mail tools:

  • Stampie, an API Wrapper for email sending providers (SendGrid, MailGun, Mandrill, SparkPost, and Mailjet)
  • Mautic, an open-source email marketing automation software. 

Choose your option according to your current needs and preferences, and don’t forget to test emails before moving to production!