Yii2在后台发送电子邮件

时间:2017-07-08 15:33:57

标签: php yii2

我有RESTful API注册用户,然后向该用户发送电子邮件以激活帐户。 这工作得很好但是有很大的延迟,因为我的代码必须发送帐户激活电子邮件,这有时需要时间。如何安排作业以后运行或在后台运行该任务?

这就是我目前正在做的事情:

actionCreateUser(){

   //HERE REGISTRATION

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

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

}

然后在前端我正在检查POST请求的响应,即数据(真或假)。

如何在后台发送电子邮件?

2 个答案:

答案 0 :(得分:2)

不久前我遇到了同样的问题。该解决方案对我来说是最佳选择。

  1. 您应该安装RabbitMQ消息系统。在Yii2中,您可以使用webtoucher/yii2-amqp扩展名。

  2. 定义您自己的消息组件。那么,您也可以重新定义邮件程序组件。您的组件必须向我们的RabbitMQ工作人员发送消息。在您的网络应用程序中,您必须使用它而不是普通的邮件程序。

  3. 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. 在Yii2的控制台应用程序中设置RabbitMQ工作程序。请注意,该工作程序是一个永久进程,但不是类似请求的进程。因此,您无法声明邮件程序组件并使用它。您必须在短时间内创建邮件程序对象。例如,仅适用于一封邮件。你可以这样做:

      $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();
      

答案 1 :(得分:1)

因为线程实现在php中很难我建议你: 如果你需要imediatly发送你的邮件,你可以写动作发送邮件,只是在你的自我行动中调用它,而不是等待结果,如果用户没有获得激活邮件,你可以为他设置一个选项再发一次。

你也必须使用cron jobs选项。默认情况下,没有实现cronjobs 您可以使用cron-manager之类的存储库或类似的东西。只需将您的信息保存在数据库中,您就可以设置每一分钟的cron选项卡运行。

yii也正在实施队列,但它已经实验了。你可以在这里看到它:https://github.com/yiisoft/yii2-queue