Learn how to configure the Zoho SMTP to send an email from a controller in Symfony 5 using the symfony mailer component.

How to send an email with a zoho email (Zoho Email SMTP) account in Symfony 5

Sending emails automatically for notifications about activity on the account of the application, sending information about updated policies, etc. is necessary on many applications. Of course, depending on the email client that you use, automatizing the process in PHP specifically using Swiftmailer in Symfony 5 isn't very intuitive.

In this article, you will learn how to easily send an email in Symfony 5 using your Zoho Email account.

1. Configure Mailer DSN

Edit your .env file and uncomment the MAILER_DSN parameter or create it if it's not in the file. The string configuration for the DSN for Zoho Email looks like this:

MAILER_DSN=smtp://<email>:<password>@smtp.zoho.com:465?encryption=ssl

In the given string you will need to replace the <email> and <password>. For example, if our email is [email protected] and password would be 12345.

MAILER_DSN=smtp://contact%40mydomain.com:[email protected]:465?encryption=ssl

The SMTP address for Zoho is smtp.zoho.com in the port 465 using the SSL encryption.

Important note: the email and password need to be URL Encoded, as you can see the email [email protected] is URL encoded, so the @ character will be replaced with %40.

2. Send an email in a controller

Now, after configuring the basics of the mailing (the access credentials), you now simply need to know how to send the email. The following controller example shows you how to send the Email. You need to import the MailerInterface, Email and TransportExceptionInterface classes on the controller and then proceed to auto inject the MailerInterface in the method where you need to send the email:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

// Include Email, Mailer and EmailException classes
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;

class PagesController extends AbstractController
{
    public function index(MailerInterface $mailer): Response
    {
        $email = (new Email())
            ->from("[email protected]")
            ->to('[email protected]')
            // Add carbon copy if you need
            ->cc('[email protected]')
            ->replyTo("[email protected]")
            ->subject("This is the subject of the Email")
            ->text("This is the content of the message")
            // If you want to send HTML instead
            //->html("<p>This is the HTML of my Email</p>")
        ;

        try {
            $mailer->send($email);
        } catch (TransportExceptionInterface $e) {
            // some error prevented the email sending; display an
            // error message or try to resend the message
        }
            
        return $this->render('pages/index.html.twig', [
            
        ]);
    }
}

As you can see it is quite simple. In some cases, depending on the implementation, you don't need to set the sender or the recipient manually, so you may define them automatically through the mailer.yaml file:

# config/packages/dev/mailer.yaml
framework:
    mailer:
        envelope:
            sender: '[email protected]'
            recipients: ['[email protected]', '[email protected]']
        headers:
            from: 'Carlos <[email protected]>'
            bcc: '[email protected]'

3. Sending a template as email content

If you are looking to send the content of a Twig view in the email, you can use the TemplatedEmail class instead of the Email. The class extends the Email class so the methods are basically the same, however, there's a new method namely htmlTemplate that receives as the first argument the path of the twig template to render. To pass variables to the Twig view, you can use the context method that receives as the first argument an array with the data that you want to pass:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

// Include Mailer
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;

class PagesController extends AbstractController
{
    public function index(MailerInterface $mailer): Response
    {
        $email = (new TemplatedEmail())
            ->from("[email protected]")
            ->to('[email protected]')
            ->subject("This is the subject of the Email")
                
            // path of the Twig template to render
            ->htmlTemplate('emails/notification.html.twig')
            // pass variables (name => value) to the template
            ->context([
                'username' => "Bruce Wayne",
            ]);

        try {
            $mailer->send($email);
        } catch (TransportExceptionInterface $e) {
            // some error prevented the email sending; display an
            // error message or try to resend the message
        }
            
        return $this->render('pages/index.html.twig', [
            
        ]);
    }
}

The Twig code of the template that we would render in the email is:

{# templates/emails/notification.html.twig #}
<h1>Welcome {{ username }}!</h1>

<p>
    Welcome to our website
</p>

Happy coding ❤️!


Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.

Sponsors