使用Cron Jobs发送电子邮件

时间:2014-03-25 07:11:58

标签: php

我有这种方法通知"我的粉丝"在添加新事件后调用。它有效,但是有多个电子邮件使得所有过程都很慢,因为弹出窗口等待所有电子邮件已经发送,然后向用户显示事件已被添加并且旋转轮将永远运行。我无法想办法在场景背后做任何事情"在用户收到已添加事件的消息之后。

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

* UPDATE * * ****

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

2 个答案:

答案 0 :(得分:3)

您正在寻找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

答案 1 :(得分:2)

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

首先,我创建了一个数据库,用于存储&#34; job&#34;必须要做的

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分钟运行一次: enter image description here

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

我希望这有助于其他人