Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Sending email

A registration confirmation, a password reset, an order notification — almost every site sends email. In Symfony the Mailer component handles it: an email is described by an object, and the delivery method is set by one configuration line.

Configuration

The delivery method is written in .env:

MAILER_DSN=smtp://user:password@smtp.example.com:587

Mail services — Mailgun, Amazon SES, Postmark and others — have ready-made packages with their own string format.

A simple email

use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
 
#[Route('/contact/send', name: 'contact_send', methods: ['POST'])]
public function send(MailerInterface $mailer): Response
{
    $email = (new Email())
        ->from('site@example.com')
        ->to('support@example.com')
        ->subject('New message')
        ->text('The text of the message');
 
    $mailer->send($email);
 
    return $this->redirectToRoute('contact');
}

Email methods

MethodWhat it sets
from(), to()Sender and recipient
cc(), bcc()Copy and blind copy
replyTo()The reply address
subject()The subject
text(), html()The content
attachFromPath()An attachment

An email from a template

Email markup is easier to keep in Twig:

use Symfony\Bridge\Twig\Mime\TemplatedEmail;
 
$email = (new TemplatedEmail())
    ->from('site@example.com')
    ->to($user->getEmail())
    ->subject('Welcome!')
    ->htmlTemplate('emails/welcome.html.twig')
    ->context(['user' => $user]);
 
$mailer->send($email);
{# templates/emails/welcome.html.twig #}
<h1>Hello, {{ user.name }}!</h1>
<p>Thank you for signing up.</p>
<a href="{{ url('profile') }}">Open your profile</a>

Emails use url() rather than path(): the recipient needs a full address with the site name.

Attachments

$email->attachFromPath('/var/www/blog/var/invoices/42.pdf', 'Invoice.pdf');

A default sender

To avoid repeating from() in every email, the address is set in the configuration:

# config/packages/mailer.yaml
framework:
    mailer:
        dsn: '%env(MAILER_DSN)%'
        envelope:
            sender: 'site@example.com'
        headers:
            From: 'My blog <site@example.com>'

Email during development

Real emails are not sent during development. There are two ways:

MAILER_DSN=null://null

Emails go nowhere but are visible in the profiler — on the E-mails tab. The second way is the Mailpit program: it accepts emails and shows them in the browser.

MAILER_DSN=smtp://localhost:1025

Common mistake

If Messenger is installed in the project, emails are not sent at once but go into a queue. Without a running worker they stay there forever, although the code runs without errors. Start php bin/console messenger:consume async or remove the SendEmailMessage line from config/packages/messenger.yaml.

Thanks for reading!

Donate to the site — we work hard for you.