Stand with Ukraine 🇺🇦 Donate to support

Sending Emails in PHP [2022 Guide with Examples]

On September 23, 2022
10min read
Viktoriia Ivanenko Technical Content Writer @ Mailtrap

Technologies advance – so does the world every day. But some things stay forever. Like sending emails with PHP. You might be skeptical and thinking even in 2022? Yes, even in 2022. W3Techs reports that, as of January 2022, “PHP is used by 78.1% of all the websites whose server-side programming language we know.” 

Toy Story Robot says "PHP everywhere"

That said, let’s check out this tutorial that will help you send emails from PHP today.

Send mail from PHP: three important things that you need to know right away

One, there is a built-in PHP mail() function and it is quite simple.

Two, although PHP’s built-in mail function () is very simple, 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. 

Three, the PHP mail function () sends emails from your website which may cause issues with deliverability due to security concerns such as suspicion of spam and blacklisting. PHP mail() also does not usually allow you to send mail using an SMTP server externally, and it does not support SMTP authentication.

What options do you have to send emails in PHP?

There are four popular ones.

  1. A built-in PHP mail() function;
  2. PHPMailer;
  3. Symfony Mailer;
  4. Third-party email sending services like Mailtrap, Sendgrid, Mailgun etc.

We’ll go step-by-step through all of them.

PHP built-in mail function () 

Mail() is  a wrapper on top of the sendmail utility, so  sendmail has to be installed in the system first.

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

  • create simple HTML/text messages without attachments and images
  •  send them to one or several recipients
  •  include additional headers to the message
  • add additional parameters to the `sendmail` command

Keep in mind that when you send emails with mail(), you may come across some grave deliverability issues. The messages dispatched will not benefit from the SPF and DKIM setup on your domain, therefore, the messages will likely be treated as spam by the receiving MTA (Mail Transfer Agent). Thus, overall deliverability of email messages sent via PHP mail () is not guaranteed. Moreover, you won’t receive bounceback messages if there is a delivery failure.

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 PHP script syntax and its main parameters. 

Syntax and parameters

The PHP mail syntax is pretty simple:

<?php
mail($to,$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. It is mandatory.
  • “$subject” = your message’s subject. 
  • “$message” = the body of your message. Lines should be separated with a LF (\n). Each line should not exceed 70 characters.
  • “[$headers]” = the mandatory one is 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.

The additional headers indicate other  recipients or copies of your message like CC or BCC. They can be an array where key is a header name and value is a header value. Or they can be a string. In this case headers should be separated with a CRLF (\r\n).

  • [$parameters] = for specifying the additional parameters defined in the sendmail_path configuration setting.

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 message part will look like this:

// Message
$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 file installation folder and configure them in the php.ini file. But this will only work for localhost or XAMPP 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. 

To send mail without SMTP, you could also refer to a third party-service like Mailtrap, SendGrid, or Mailgun. 

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 like Symfony Mailer. Or the third-party solution.

How to send emails using PHP via the contact form?

There are also a couple of ways to do this. And this topic needs a special tutorial. Either you run a WordPress website, or need a simple contact form, check out this encoding for a PHP contact form with Google reCaptcha. 

We explain how it works in detail, plus we go through many other ways to create contact forms in PHP in our special guide on PHP code to send email from a contact form. Tune in.

<?php
$errors = [];
$errorMessage = '';
$successMessage = '';
$secret = 'your site key';

if (!empty($_POST)) {
  $name = $_POST['name'];
  $email = $_POST['email'];
  $message = $_POST['message'];
  $recaptchaResponse = $_POST['g-recaptcha-response'];
  $recaptchaUrl = "https://www.google.com/recaptcha/api/siteverify?secret={$secret}&response={$recaptchaResponse}";
  $verify = json_decode(file_get_contents($recaptchaUrl));
  
  if (!$verify->success) {
    $errors[] = 'Recaptcha failed';
  }
  if (empty($name)) {
    $errors[] = 'Name is empty';
  }
  if (empty($email)) {
    $errors[] = 'Email is empty';
  }
  else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $errors[] = 'Email is invalid';
  }
  if (empty($message)) {
    $errors[] = 'Message is empty';
  }

  if (!empty($errors)) {
    $allErrors = join('<br/>', $errors);
    $errorMessage = "<p style='color: red;'>{$allErrors}</p>";
  } else {
    $toEmail = 'example@example.com';
    $emailSubject = 'New email from your contant form';
    $headers = ['From' => $email, 'Reply-To' => $email, 'Content-type' => 'text/html; charset=iso-8859-1'];
    $bodyParagraphs = ["Name: {$name}", "Email: {$email}", "Message:", $message];
    $body = join(PHP_EOL, $bodyParagraphs);
    if (mail($toEmail, $emailSubject, $body, $headers)) {
      $successMessage = "<p style='color: green;'>Thank you for contacting us :)</p>";
    }
    else {
      $errorMessage = "<p style='color: red;'>Oops, something went wrong. Please try again later</p>";
    }
  }
}
?>

<html>
  <body>
    <script src="https://www.google.com/recaptcha/api.js"></script>
    <form action="/form.php" method="post" id="contact-form">
      <h2>Contact us</h2>
      <?php echo((!empty($errorMessage)) ? $errorMessage : '') ?>
      <?php echo((!empty($successMessage)) ? $successMessage : '') ?>
      <p>
        <label>First Name:</label>
        <input name="name" type="text"/>
      </p>
      <p>
        <label>Email Address:</label>
        <input style="cursor: pointer;" name="email" type="text"/>
      </p>
      <p>
        <label>Message:</label>
        <textarea name="message"></textarea>
      </p>
      <p>
        <button
        class="g-recaptcha"
        type="submit"
        data-sitekey="your site key"
        data-callback='onRecaptchaSuccess'
        >
          Submit
        </button>
      </p>
    </form>

    <script>
    function onRecaptchaSuccess() {
      document.getElementById('contact-form').submit()
    }
    </script>
  </body>
</html>

How to send emails with PHPMailer?

PHPMailer is the classic and the most popular email sending library for PHP. It deserves a separate article and a tutorial. To get a detailed overview of the php code in PHPMailer read our guide on how to send emails using PHPMailer.

What you can do with PHPMailer

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

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

Now let’s send, say, a hotel 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 = 528;

$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 // just add the '/path/to/file.pdf', 'filename.pdf'
$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';
}

Pay attention: for this email message we use the following piece of code

$mail->isSMTP();
$mail->Host = 'smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = '1a2b3c4d5e6f7g';
$mail->Password = '1a2b3c4d5e6f7g';
$mail->SMTPSecure = 'tls';
$mail->Port = 528;

to set the mail server, SMTP port, and enable email authentication. 

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. Moreover, it causes some serious deliverability issues. So we would recommend using some external mailing packages instead. For 2022, Pear:: Mail and Swift Mailer are not a thing anymore (as they are outdated now), so the obvious choice would be Symfony Mailer. 

Symfony Mailer & Mime components establish a solid system for creating and sending emails – complete with support for multipart messages, Twig integration, CSS inlining, file attachments etc. We have created a step-by-step guide for Sending emails in Symphony: from installation to transport set up, and creating and sending messages. Feel free to use it to your davantage. Do not hesitate to turn to current 6.1 version documentation for specific details.

Mind that here we show a standalone usage of this package, and it’s already integrated into Symfony and into Laravel framework. So using it is simpler while working with the frameworks altogether.

<?php

use Symfony\Component\Mailer\Mailer; 
use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; 
use Symfony\Component\Mime\Email;

require_once './vendor/autoload.php';


$transport = (new EsmtpTransport('smtp.mailtrap.io', 2525, false))
                ->setUsername('155d3ee688e2b6')
                ->setPassword('1ca3b8a278cf32');

$mailer = new Mailer($transport); 

$email = (new Email())
            ->from('hello@example.com')
            ->to('you@example.com')
            ->subject('Time for Symfony Mailer!')
            ->text('Sending emails is fun again!')
            ->html('<p>See Twig integration for better HTML integration!</p>');

$mailer->send($email);    

Sending emails in PHP with third-party email services 

In case your application requires automated email sending and email analytics, it is always better to go for the third-party email services. Why? It is faster, it is less labor and resource-consuming, and let’s be honest: it gives you more control over email infrastructure.

There are many third-party email services you can integrate your app with, such as Sendgrid, Mailgun etc. But, the Mailtrap Delivery Platform might arguably be the one you actually need.

Using Mailtrap to send emails with PHP

If you’re looking for a reliable and hassle-free email sending service with PHP, you should probably consider the Mailtrap Email API. It’s an Email API/SMTP Relay that allows for up to 60 days of email logs for improved troubleshooting (saving your hard data during this time span). 

Dashboards with a clear snapshot of the state of your email infrastructure are always at hand for analytics. 

Mailtrap application dashboard snippet

Another advantage of Mailtrap email API is our timely email deliverability alerts that give you greater control over your email infrastructure and domain authority. This means that if anything goes wrong with your deliverability, you get an alert with a color-coded table plus insights on where to inspect a deliverability issue. Yet, Mailtrap sends you regular weekly reports on your deliverability performance to keep you up to date with your email sending and deliverability performance.

Snippet of Deliverability alerts from Mailtrap

Mailtrap API integration for PHPGo to the Sending Domains tab, choose API/SMTP Integration, go for the API one,  and select PHP from the library.
You’ll find the necessary credentials right there, just copy and paste them:

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => 'https://send.api.mailtrap.io/api/send',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{"from":{"email":"mailtrap@mailtrap.club","name":"Mailtrap Test"},"to":[{"email":"viktoriia.ivanenko@railsware.com"}],"subject":"You are awesome!","text":"Congrats for sending test email with Mailtrap!","category":"Integration Test"}',
    CURLOPT_HTTPHEADER => array(
        'Authorization: Bearer <your api token>,
        'Content-Type: application/json'
    ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

Now you can start sending.

Try Sending Emails in PHP with Mailtrap for Free

Server configuration

Here is how your SMTP server configuration to start sending with PHP would look like in Mailtrap for PHPMailer (go to SMTP credentials at Mailtrap interface, then just copy and paste them):

<?php
// configure an SMTP
$mail->isSMTP();
$mail->Host = 'smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = 'api';
$mail->Password = '********2ff0';
$mail->SMTPSecure = 'tls';
$mail->Port = 528;

Three common issues with PHP mails

We’ll cover only the basic issues here. In case you have a specific problem not mentioned here, refer to the PHP documentation, or the sending service providers’ support.

Wrongly displayed characters

Let’s say the email doesn’t render German characters (umlauts) properly.

Then, you need to set the Content-Type and the Charset in the headers of the email:

<?php
$headers = 'Content-Type: text/plain; charset=utf-8' . "\r\n";
?>

Mostly, UTF-8 is your best choice.

Then, add the following header too:

<?php
$headers .= 'Content-Transfer-Encoding: base64' . "\r\n";
?>

Now, you can use both UTF-8 and Base64 to properly encode the subject line or the recipient name if they require specific characters.

<?php
$subject = '=?UTF-8?B?' . base64_encode('Test email with German Umlauts öäüß') . '?=';
$recipient = '=?UTF-8?B?' . base64_encode('Margret Müller') . '?= <recipient@domain.com>';
?>

And don’t forget to Base64 encode the email message too:

<?php
$message = base64_encode('This email contains German Umlauts öäüß.');
?>

Windows and Linux configurations

Troubles might come if your PHP is not configured properly in the php.ini file. 

For Windows users, it should somewhat look like this:

[mail function]
; For Win32 only.
SMTP = smtp.secureserver.net

; For win32 only
sendmail_from = webmaster@mailtrap.io

Linux users simply need to let PHP know the location of their sendmail application. The path and any desired switches should be specified to the sendmail_path directive.

The configuration for Linux should look something like this:

[mail function]
; For Win32 only.
SMTP = 

; For win32 only
sendmail_from = 

; For Unix only
sendmail_path = /usr/sbin/sendmail -t -i

PHP mail function is not sending the email

This could be pretty tricky. However, here are a few things you can do to handle it:

  • Make sure your mail() function is called properly. (If one of the three parameters is not correct, it will fail sending);
  • Check for port connection (If you share a hosting server, the ports 25 and 587 remain blocked by default. Then, you need to use the 2525 port);
  • Ensure all headers are provided and have the correct syntax;
  • Check if your MTA/web server setup is right. You can use Mailtrap for this purpose.

Anyway, troubleshooting and testing needs some special attention and in-depth analysis. Here, you can find out more about how to test emails sent from PHP.

Final considerations

In this article, we have described the basic PHP email sending principles, syntax, and parameters. We’ve also reviewed the main ways of sending emails with PHP: its built-in mail function and the most popular external mail package. 

However, in many situations, you might consider using a third-party mail service integration like Mailtrap to save time, money, and effort.

Article by Viktoriia Ivanenko Technical Content Writer @ Mailtrap