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

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 contact@mydomain.com and password would be 12345.

MAILER_DSN=smtp://contact%40mydomain.com:12345@smtp.zoho.com: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 contact@mydomain.com 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("contact@mydomain.com")
            ->to('client@somedomain.com')
            // Add carbon copy if you need
            ->cc('other@mydomain.com')
            ->replyTo("email_of_the_one_who_sends@somedomain.com")
            ->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: 'carlos@mydomain.com'
            recipients: ['foo@example.com', 'bar@example.com']
        headers:
            from: 'Carlos <carlos@mydomain.com>'
            bcc: 'baz@example.com'

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("contact@mydomain.com")
            ->to('client@somedomain.com')
            ->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 ❤️!

This could interest you

Become a more social person