简体   繁体   English

Yii2在后台发送电子邮件

[英]Yii2 sending emails in the background

I have a RESTful API which registers a user and later sends an email to that user for account activation. 我有一个RESTful API ,可以注册一个用户,然后向该用户发送电子邮件以激活帐户。 This works just fine but there is a great delay, since my code has to send the account activation email which sometimes takes time. 这工作得很好,但是会有很大的延迟,因为我的代码必须发送帐户激活电子邮件,这有时会花费一些时间。 How can I schedule jobs to run later or in the background for that task? 如何安排作业在以后或在后台运行该任务?

This is what I am doing currently: 这是我目前正在做的事情:

actionCreateUser(){

   //HERE REGISTRATION

  if($model->save()){  //successifull registration

    //send email here which takes time
    if($emailsent){
      return ["data"=>true];
     }else{
        return ["data"=>false];
     }
   }

}

Then in the front-end I am checking the response of the POST request which is data(true or false). 然后在前端,我正在检查POST请求的响应,该响应是data(true或false)。

How can I send the email in the background? 如何在后台发送电子邮件?

I had the same problem not so long ago. 不久前我遇到了同样的问题。 The solution looks optimal for me. 该解决方案对我来说似乎是最佳的。

  1. You should install RabbitMQ message system. 您应该安装RabbitMQ消息系统。 In Yii2 you can use webtoucher/yii2-amqp extension. 在Yii2中,您可以使用webtoucher/yii2-amqp扩展名。

  2. Define you own message component. 定义您自己的消息组件。 Well, you can also redefine mailer component. 好了,您也可以重新定义邮件程序组件。 Your component must send message to our RabbitMQ worker. 您的组件必须向我们的RabbitMQ工作人员发送消息。 In your web-application you have to use it instead of normal mailer. 在您的Web应用程序中,您必须使用它而不是普通邮件程序。

use Yii;
use yii\base\Component;
use yii\base\InvalidConfigException;
use yii\base\ErrorException;
use PhpAmqpLib\Message\AMQPMessage;

use webtoucher\amqp\components\Amqp;

class MessengerComponent extends Component
{

    protected $_recipient;
    protected $_subject;
    protected $_message_view;
    protected $_params;
    protected $_to;

    public function send()
    {

        $msg = [
            'to' => $this->_to,
            'message_view' => $this->_message_view,
            'subject' => $this->_subject,
            'params' => $this->_params,
        ];

        try {
            if(! YII_ENV_TEST)
                Yii::$app->amqp->send('send-message', 'send_message', $msg, Amqp::TYPE_DIRECT);
            return true;
        } catch(\Exception $e) {
            return false;
        }
    }
}
  1. Set up your RabbitMQ worker in your console application of Yii2. 在Yii2的控制台应用程序中设置RabbitMQ worker。 Note, that worker is a permanent process but not a request-like. 请注意,该工作程序是一个永久过程,而不是类似于请求的过程。 So, you cannot declare mailer component and use it. 因此,您不能声明邮件程序组件并使用它。 You have to create mailer object only for a short time. 您只需要短时间创建mailer对象。 For example, only for one mail. 例如,仅用于一封邮件。 You can do this like that: 您可以这样做:

     $mailer = Yii::createObject([ 'class' => 'yii\\swiftmailer\\Mailer', 'viewPath' => '@common/mail', 'transport' => [ 'class' => 'Swift_SmtpTransport', 'host' => 'mail.host.domain', 'username' => 'mail username', 'password' => 'mail passwork', 'port' => '465', 'encryption' => 'SSL', ], ]); $mailer ->compose( ['html' => $html, 'text' => $text], $this->params ) ->setFrom([Yii::$app->params['systemEmail'] => Yii::t('app', '{service} email title', [ 'service' => Yii::$app->name] ->setTo($this->email) ->setSubject($this->subject) ->send(); 

as thread implemntation is hard in php I suggest you to: if you need to imediatly send your mail you can write action to send mail and just call it in your self action and don't wait for result and if user didn't got activation mail you can set an option for him to send it again. 因为在PHP中很难实现线程禁止,所以我建议您:如果您需要立即发送邮件,则可以编写操作来发送邮件,并在自己的操作中调用它,而不必等待结果并且用户没有被激活邮件,您可以设置一个选项让他再次发送。

you have to use cron jobs options too.by default yii don't implemented cronjobs you can use repository like cron-manager or something like this.just save your information in db and you can set every one minute your cron tab to run. 您也必须使用cron作业选项。默认情况下,yii不实现cronjobs,您可以使用cron-manager之类的存储库或类似的东西。只需将您的信息保存在db中,就可以设置每分钟运行cron选项卡的时间。

yii also is implementing queue but it's experimental yet.you can see it here : https://github.com/yiisoft/yii2-queue yii也正在实现队列,但是还处于试验阶段。您可以在这里查看它: https : //github.com/yiisoft/yii2-queue

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM