Sending mail in Symfony
last modified July 5, 2020
Symfony mail tutorial shows how to send a simple mail in Symfony. Symfony uses SwiftMailer to send emails.
Symfony
Symfony is a set of reusable PHP components and a PHP framework for web projects. Symfony is free software with some commertial addons. Symfony was inspired by Ruby on Rails, Django, and the Spring Framework.
SwiftMailer
SwiftMailer
is a free feature-rich PHP mailer. Symfony integrates
SwiftMailer via its symfony/swiftmailer-bundle
.
Symfony send mail example
In the example, we have send a simple email. We use Twig to create an email template.
Setting up the application
We start with setting up the application with composer.
$ composer create-project symfony/skeleton mail $ cd mail
We create a new Symfony skeleton project and go the the newly created project directory.
$ composer req twig annotations monolog
We install three basic Symfony packages needed for a web application.
$ composer req symfony/swiftmailer-bundle
We install the symfony/swiftmailer-bundle
.
$ composer req maker server --dev
We install packages for development: maker
and server
.
... MAILER_URL=smtp://smtp.example.com:465?encryption=ssl&auth_mode=login&username=admin@example.com&password=s$cret
In the .env
file, we set the MAILER_URL
variable. It contains the
SMTP server that is going to deliver the emails. If you are a beginner, avoid using Gmail because
setting up Gmail correctly is a complex task due to Gmail's high level of security.
Instead, use an SMTP server from your hosting provider, or a service such as mailgun or mailtrap. The necessary options such as port number and encryption is given by the provider/service.
$ php bin/console make:controller TestMailController
We create a TestMailController
that contains a simple link to
send an email.
<?php namespace App\Controller; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; class TestMailController extends AbstractController { /** * @Route("/test/mail", name="test_mail") */ public function index(Request $request, \Swift_Mailer $mailer, LoggerInterface $logger) { $name = $request->query->get('name'); $message = new \Swift_Message('Test email'); $message->setFrom('admin@zetcode.com'); $message->setTo('admin2@zetcode.com'); $message->setBody( $this->renderView( 'emails/mymail.html.twig', ['name' => $name] ), 'text/html' ); $mailer->send($message); $logger->info('email sent'); $this->addFlash('notice', 'Email sent'); return $this->redirectToRoute('home'); } }
In the TestMailController's
index()
method, we
send the email. Note that code sending email should not be in a controller
in a production application; it should be in some service. But for simplicity
reasons, we leave it here.
public function index(Request $request, \Swift_Mailer $mailer, LoggerInterface $logger) {
We inject the Request
, Swift_Mailer
, and the logger.
$name = $request->query->get('name');
We get the name that is used in the GET request.
$message = new \Swift_Message('Test email'); $message->setFrom('example@example.com'); $message->setTo('example2@example.com');
A Swift_Message
is created. The from and to email values are hard-coded
to make this example simpler. You can remove the hard-coded values as an exercise.
(Set the source email as a parameter, fetch the destination email from a form.)
$message->setBody( $this->renderView( 'emails/mymail.html.twig', ['name' => $name] ), 'text/html' );
With the setBody()
, we set the body of the email. The renderView()
method renders the view from the provided Twig template. We pass the $name
variable to the template.
$mailer->send($message);
The email is sent with send()
.
$logger->info('email sent'); $this->addFlash('notice', 'Email sent');
We log & flash a message. The flash message is displayed after the email is successfully sent.
return $this->redirectToRoute('home');
We redirect to the home page, where the flash message is shown.
Hi {{ name }}! You've got a test email. Thanks!
This is a simple template for the email.
$ php bin/console make:controller HomeController
We create a HomeController
. It contains a simple link to
send an email.
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Routing\Annotation\Route; class HomeController extends AbstractController { /** * @Route("/", name="home") */ public function index() { return $this->render('home/index.html.twig'); } }
The HomeController
renders the home page.
{% extends 'base.html.twig' %} {% block title %}Home page{% endblock %} {% block stylesheets %} <style> .flash-notice { margin: 8px; padding-left: 8px; width: 150px; background-color: rgb(113, 241, 113) } .hide { opacity: 0; transition: opacity 1000ms; } </style> {% endblock %} {% block body %} <a href="/test/mail?name=Peter Novak">Send a test mail</a> {% for message in app.flashes('notice') %} <div id="flash-notice" class="flash-notice"> {{ message }} </div> {% endfor %} {% block javascripts %} <script src="main.js"></script> {% endblock %} {% endblock %}
The home page contains a link for sending an email. If the email is sent, we show a notification. This notification can be hidden by clicking on it.
<style> .flash-notice { margin: 8px; padding-left: 8px; width: 150px; background-color: rgb(113, 241, 113) } .hide { opacity: 0; transition: opacity 1000ms; } </style>
We set some styling for the notification. Also, the hide
class
provides a simple fadeout animation. The animation is lauched in JavaScript by
inserting this class into the notification element.
<a href="/test/mail?name=Peter Novak">Send a test mail</a>
This link makes a GET request that triggers an email. We send a name
attribute with the request. The name is hard-coded; as an exercise, you can
create a form that will specify the name and the destination email.
{% for message in app.flashes('notice') %} <div id="flash-notice" class="flash-notice"> {{ message }} </div> {% endfor %}
If there is a flash message, we show it.
<script src="main.js"></script>
The animation is controlled in JavaScript code, which is located
in the main.js
file.
const flash = document.getElementById('flash-notice'); flash.addEventListener('click', function () { flash.classList.add('hide'); });
When we click on the flash message, the event callback adds the
hide
class into the class list of the element, thus
starting a fadeout animation.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{% block title %}Welcome!{% endblock %}</title> {% block stylesheets %} {% endblock %} </head> <body> {% block body %}{% endblock %} {% block javascripts %}{% endblock %} </body> </html>
This is the base Twig template.
In this tutorial we have shown how to send a simple email in Symfony.
List all Symfony tutorials.
See Mailtrap's How to Send Emails in Symfony with Examples.