【问题标题】:Send Emails behind the scene with Cron Jobs使用 Cron Jobs 在幕后发送电子邮件
【发布时间】:2014-03-25 07:11:57
【问题描述】:

我有这个方法来通知“我的追随者”,这是在添加新事件后调用的。它可以工作,但是使用多于一封电子邮件会使所有过程非常缓慢,因为弹出窗口会等待所有电子邮件都已发送,然后再向用户显示已添加事件并且旋转轮将永远运行。在用户收到事件已添加的消息后,我想不出任何方法来“在幕后”进行操作。

public function notifiedFollowers($creator_id, $type, $event_id){
   $query = $this->_db->prepare("SELECT * FROM followers WHERE user_id = ?");
   $query->bindParam(1, $creator_id, PDO::PARAM_INT);
   $query->execute();


      while($row = $query->fetch(PDO::FETCH_OBJ)) {

         $creator  = new User($creator_id);
         $creatorName = $creator->data()->name;
         $user = new User($row->followers_id);
         $mail = new PHPMailer();
         $template = New MailFactory();
         $mail->IsSMTP(); 
         $mail->Host = "myHost";  
         $mail->SMTPAuth = true; 
         $mail->Username = "myUser";
         $mail->Password = "myPassword";
         $mail->IsHTML(true);    
         $mail->From = 'from email';
         $mail->FromName = 'from name';
         $mail->AddAddress($user->data()->username); 
         $mail->Subject = 'add subject here';
         $mail->Body    = $template->notifiedFollowersEmail($creatorName, $user->data()->name, $type, $event_id);
            if(!$mail->send()) {
              echo $mail->ErrorInfo;
              die();
             }
      }
}

*更新******

我使用 cron 作业解决了这个问题。请检查我的答案。

【问题讨论】:

    标签: php


    【解决方案1】:

    您正在寻找Threads

    <?php
    class AsyncEmail extends Thread {
    
        public function __construct($arg){
            $this->arg = $arg;
        }
    
        public function run() {
            /** Add your email sending code here. **/
        }
    }
    
    // and call this following lines in loop
    $aEmail = new AsyncEmail( $arg );
    var_dump($aEmail->start());
    ?>
    

    此代码将在您的代码后台异步运行,您的用户无需等待任何步骤完成。

    看看这个PHP threading call to a php function asynchronously

    【讨论】:

    • 谢谢。我必须使用函数run() 还是可以在类中复制我的函数?
    • 复制运行中的函数并在循环中调用$aEmail-&gt;start()
    • 对不起,我可以在start($creator_id, $type, $event_id)里面传递变量吗?
    • 不创建数组/对象并通过类发送并在构造函数中设置。检查更新。
    • 在你的情况下发送对象$mail并在运行中调用$mail-&gt;send()
    【解决方案2】:

    我终于找到了完美的解决方案:Cron Job

    首先我创建了一个数据库来存储必须完成的“工作”

    CREATE TABLE IF NOT EXISTS `cron_jobs_new_event` (
      `cron_job_id` int(32) NOT NULL AUTO_INCREMENT,
      `event_id` int(32) NOT NULL,
      `user_id` int(32) NOT NULL,
      `notify` int(32) NOT NULL,
      `executed` int(11) NOT NULL DEFAULT '0',
      PRIMARY KEY (`cron_job_id`),
      KEY `event_id` (`event_id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
    
    --
    -- Constraints for table `cron_jobs_new_event`
    --
    ALTER TABLE `cron_jobs_new_event`
      ADD CONSTRAINT `cron_jobs_new_fk` FOREIGN KEY (`event_id`) REFERENCES `event` (`event_id`) ON DELETE CASCADE ON UPDATE CASCADE;
    

    我使用 hostgator,因此我将 cron 作业设置为每 15 分钟运行一次:

    cron.php 只需从我的class Notification 调用一个方法

    <?php require 'core/init.php';
    
    $notification = new Notification();
    $notification->notifiedFollowers();
    

    这是我的神奇方法(至少对我而言 ;-)

         public function notifiedFollowers(){
    
            $query = $this->_db->prepare("SELECT user_id FROM cron_jobs_new_event WHERE executed = '0' AND notify = '1'");
            $query->execute();
            while($row = $query->fetch(PDO::FETCH_OBJ)) {
                $userCreator = $row->user_id;
                        $q = $this->_db->prepare("SELECT * FROM followers WHERE user_id = ?");
                            $q->bindParam(1, $userCreator, PDO::PARAM_INT);
                                $q->execute();
    
                                        while($followers = $q->fetch(PDO::FETCH_OBJ)) {
    
                                            $type='try';
                                            $creator  = new User($followers->user_id);
                                            $creatorName = $creator->data()->name;
                                            $userFollower = new User($followers->followers_id);
                                            $mail = new PHPMailer();
                                            $template = New MailFactory();
                                            $mail->IsSMTP(); 
                                            $mail->Host = "my host";  
                                            $mail->SMTPAuth = true; 
                                            $mail->Username = "my username";
                                            $mail->Password = "myPassword";
                                            $mail->IsHTML(true);    
                                            $mail->From = 'ev';
                                            $mail->FromName = 'Events Team';
                                            $mail->AddAddress($userFollower->data()->username); 
                                            $mail->Subject = 'Somebody add a new event!';
                                            $mail->Body    = $template->notifiedFollowersEmail($creatorName, $userFollower->data()->name, $type, $followers->event_id);
    
                                            if(!$mail->send()) {
                                            echo $mail->ErrorInfo;
                                            die();
                                            }
                                        }
    //here I update the database so next time the cron runs, It won't send the same message
                            $update = $this->_db->prepare("UPDATE cron_jobs_new_event SET executed = '1'  WHERE cron_job_id =  ?");
                            $update->bindParam(1, $row->cron_job_id, PDO::PARAM_INT);
                            $update->execute();
                }
            }
    

    我希望这对其他人有帮助

    【讨论】:

      猜你喜欢
      • 2017-12-21
      • 2016-03-20
      • 2011-04-26
      • 2018-11-15
      • 1970-01-01
      • 1970-01-01
      • 2010-11-26
      • 2015-10-22
      • 1970-01-01
      相关资源
      最近更新 更多