How to send emails in Symfony

Updated: January 13, 2024 By: Guest Contributor Post a comment

Introduction

Symfony is a set of reusable PHP components and a web application framework that allows developers to create scalable, high-performing web applications. A common task in web applications is sending emails. In this tutorial, we will go over how to send emails in Symfony using the most up-to-date practices. We’ll start with a simple example and progress to more advanced scenarios, providing code samples and expected outputs.

Setting Up

Before we can send emails, we need to install the required components and configure SwiftMailer, which is Symfony’s default mailer component. Begin by installing the mailer via Composer:

composer require symfony/swiftmailer-bundle

After installation, configure the mailer parameters under config/packages/swiftmailer.yaml:

swiftmailer:
    transport: '%env(MAILER_TRANSPORT)%'
    host:      '%env(MAILER_HOST)%'
    username:  '%env(MAILER_USER)%'
    password:  '%env(MAILER_PASSWORD)%'
    spool: { type: memory }

You also need to set the environment variables in the .env file:

# .env

# Email configuration
MAILER_TRANSPORT=smtp
MAILER_HOST=mail.example.com
[email protected]
MAILER_PASSWORD=secret

Basic Email Sending

Below is a simple example of sending an email:

public function sendEmail(MailerInterface $mailer)
{
    $email = (new Email())
        ->from('[email protected]')
        ->to('[email protected]')
        ->subject('Time for Symfony Mailer!')
        ->text('Sending emails is fun again!');

    $mailer->send($email);

    // Add logic here to respond to the email sending action
}

This code can be placed inside a controller method. It sends a plain text email using the Symfony Mailer component. Once executed, the mailer sends out the email with the specified content.

Using Templates

For more complex emails, you can use templating engines like Twig to generate the email content. First, install Twig if you haven’t already:

composer require twig

Next, you can create a Twig template for your email:

{# templates/emails/registration.html.twig #}
<h1>Welcome to the site!</h1>
<p>Hello {{ name }}! Thank you for registering on our site.</p>

Now, let’s modify the sendEmail function to use this template:

use Symfony\Bridge\Twig\Mime\TemplatedEmail;

public function sendEmail(MailerInterface $mailer, Environment $twig, $userName)
{
    $email = (new TemplatedEmail())
        ->from('[email protected]')
        ->to('[email protected]')
        ->subject('Welcome to Symfony Sites!')
        ->htmlTemplate('emails/registration.html.twig')
        ->context(['name' => $userName]);

    $mailer->send($email);
}

With this setup, the sendEmail function now uses a Twig template to send a styled HTML email. The email renders the template with the passed userName variable.

Handling Attachments

Attaching files to an email is another common requirement. Symfony Mailer makes handling attachments straightforward. Here’s how:

use Symfony\Component\Mime\Email;

public function sendEmailWithAttachment(MailerInterface $mailer)
{
    $email = (new Email())
         ->from('[email protected]')
         ->to('[email protected]')
         ->subject('Here is your attachment')
         ->text('Please find the attached file.')
         ->attachFromPath('/path/to/file.pdf', 'document.pdf');

    $mailer->send($email);
}

In this example, attachFromPath() adds an attachment to the email. The attachment can be named differently from the source file by specifying the second parameter.

Configuring Spooling

Spooling emails allows your application to respond to requests quickly by deferring email delivery to a later time. Symfony provides a spool feature that keeps emails in memory and sends them after the response is served. The spool configuration was shown earlier in the SwiftMail configuration.

To make sure emails are sent after your response, you need to set up an event listener or use built-in Symfony commands:

// In a command or controller

$this->get('mailer')->flushQueue();

This line would flush the spool queue, causing all emails to be sent.

Advanced Scenario: Enqueue Bundle

For larger applications, you might want to opt for a message queue to handle email delivery, ensuring even greater performance and reliability. Symfony integrates with the Enqueue bundle to provide this functionality. First, install the Enqueue bundle and a transport, such as the AMPQ bundle:

composer require enqueue/enqueue-bundle enqueue/amqp-bundle

Then configure the bundle to use your selected message broker, and have your MailerInterface service to send messages through it.

Conclusion

Sending emails in Symfony can range from very simple setups with default components to complex and high-performing solutions with message queues. Following this tutorial, you’ve learned how to send basic emails with templating support, handle attachments, implement email spooling, and queue emails for better performance in Symfony applications.