【问题标题】:Symfony 5 : send both sync and async mails in the appSymfony 5:在应用程序中发送同步和异步邮件
【发布时间】:2022-01-24 13:29:00
【问题描述】:

我想在我的 symfony 应用程序中以同步和异步模式发送电子邮件。我遵循了 symfony messenger 的文档,但我对一个关键参数有疑问:路由

framework:
   messenger:
      async: '%env(MESSENGER_TRANSPORT_DSN)%'
      routing:
           'Symfony\Component\Mailer\Messenger\SendEmailMessage':  async

使用此配置,所有消息都在队列中发送。

我有 2 个服务,我在第一个发送电子邮件同步,在第二个发送异步:

<?php

namespace App\Service;

use Symfony\Component\Mime\Address;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\Mailer\MailerInterface;

    class MailManagerAsync
    {
        protected $mailer;
    
        public function __construct(MailerInterface $mailer)
        {
            $this->mailer = $mailer;
        }
    
        protected function sendMessage($subject, $body, $bodyText, $to, $context=[])
        {
            $email = (new TemplatedEmail())
                ->from($this->from)
                ->to(new Address($to))
                ->subject($subject)
    
                // path of the Twig template to render
                ->htmlTemplate($body)
                ->textTemplate($bodyText)
    
                // pass variables (name => value) to the template
                ->context($context)
            ;
    
            $this->mailer->send($email);
        }
    
        // function where i send emails
    
    }

第二个与第一个相同,称为 MailManagerSync。

现在问题来了: 当我像这样更改路由时:

routing : 'App\Service\MailManagerAsync':  async

应用程序正在发送 2 封电子邮件,其中 1 封已排队,1 封已发送。我只想发送一个 QUEUED。

有什么建议吗?

编辑:我知道我必须创建一个消息类,并将其发送到总线,但是: 是否有任何简单的解决方案可以同时拥有同步和异步电子邮件,而无需开发我上面所说的所有内容?

【问题讨论】:

  • 您正在将服务添加到路由配置中。它不是那样工作的。您映射的是 message 类,而不是服务。
  • 是的,这就是我所理解的。但是如何将服务作为消息类传递? (也许扩展一些类?)
  • 不,您不会将服务作为消息对象传递。服务应该只是一个消息处理程序,消息只是一个数据传输对象。
  • 好的,我明白了。但是有什么简单的解决方案可以同时拥有同步和异步电子邮件,而无需开发消息类等等?
  • 我们几天前讨论过this exact same thing...

标签: php symfony mailer


【解决方案1】:

好的,这是一个可以帮助其他人的解决方案。我想我没有带它,因为这个使者的东西相对较新。

首先创建一个消息类:

<?php

namespace App\Message;

class EmailAsync
{
    private $subject;

    private $body;

    private $bodyText;

    private $recipient;

    private $context = [];

    public function __construct($subject, $body, $bodyText, $recipient, $context)
    {
        $this->subject = $subject;
        $this->body = $body;
        $this->bodyText = $bodyText;
        $this->recipient = $recipient;
        $this->context = $context;
    }
// setters and getter

这个类将传输电子邮件。 然后是处理程序:

<?php

namespace App\MessageHandler;

use App\Message\EmailAsync;
use Symfony\Component\Mime\Address;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;

class EmailAsyncHandler  implements MessageHandlerInterface 
{

    protected $mailer;
    
    public function __construct(MailerInterface $mailer)
    {
        $this->mailer = $mailer;
    }

    public function __invoke(EmailAsync $email)
    {
        $subject = $email->getSubject();
        $body = $email->getBody();
        $bodyText = $email->getBodyText();
        $recipient = $email->getRecipient();
        $context = $email->getContext();

        $emailToSend = (new TemplatedEmail())
            ->from("my-address@hello.com")
            ->to(new Address("your-address@hello.com"))
            ->subject($subject)

            // path of the Twig template to render
            ->htmlTemplate($body)
            ->textTemplate($bodyText)

            // pass variables (name => value) to the template
            ->context($context)
        ;

        $this->mailer->send($emailToSend);
    }
}

现在你可以设置正确的路由参数了:

framework:
    messenger:
        transports:
            async: '%env(MESSENGER_TRANSPORT_DSN)%'

        routing:
            # Route your messages to the transports
            'App\Message\EmailAsync':  async

现在如果我想发送异步邮件,我会在我的服务中使用总线:

<?php

namespace App\Service;

use App\Message\EmailAsync;
use Symfony\Component\Messenger\MessageBusInterface;

class MailManagerAsync
{
    protected $bus;

    public function __construct(MessageBusInterface $bus)
    {
        $this->bus = $bus;
    }

    protected function sendMessage($subject, $body, $bodyText, $to, $context = [])
    {
        $emailAsync = new EmailAsync($subject, $body, $bodyText, $to, $context);
        $this->bus->dispatch($emailAsync);
    }

// SEND EMAILS

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多