【问题标题】:Cakephp Email after several seconds/minutes几秒/分钟后的 Cakephp 电子邮件
【发布时间】:2013-04-09 11:54:39
【问题描述】:

cakephp中是否有在指定时间内发送电子邮件?

我有一个使用 cakephp 构建的文件上传网站,上传完成后它会发送一封电子邮件以获取下载链接,然后它会调用一个 php CLI 来压缩文件。在压缩过程中,站点已经关闭,所以我不知道压缩过程什么时候结束。我想知道是否可以在 cakephp 电子邮件中指定,例如在刷新页面之前 1 分钟后发送电子邮件。

这是一些显示发生了什么的代码

var xhr_zip;
xhr_zip = new XMLHttpRequest();
fd_zip = new FormData();
fd_zip.append("total_files", total_files);
xhr_zip.open("POST", "datas/zip/", true);
xhr_zip.send(fd_zip);

xhr_update_usage = new XMLHttpRequest();
fd_update_usage = new FormData();
xhr_update_usage.open("POST", "datas/update_usage/", true);
xhr_update_usage.send(fd_update_usage);

xhr_email = new XMLHttpRequest();

fd_email = new FormData();

xhr_email.open("POST", "datas/send_link/" + recipient + '/' + subject, true);
xhr_email.send(fd_email);

    xhr_email.onload = function(e) {
        setTimeout(function() {
            $("body").removeClass("loading");
            window.onbeforeunload = null;
            alert("Total Files : " + total_files + " Sent \n Total Upload Size : " + (total_upload_size/1048576).toFixed(2) + " MB");                   
            document.location.reload(true);
        }, 2000);
    };

因此,在 zip 触发后,即使未完成压缩,脚本也会继续发送电子邮件并刷新浏览器。

【问题讨论】:

  • 压缩后为什么不发送邮件
  • @Dagon 因为压缩是通过 php 完成的,而通过 CakePHP 发送电子邮件。这就像 2 个不同的应用程序。所以,如果我必须在压缩后这样做,我需要将代码移动到标准 PHP 代码中,我尽量不这样做
  • cake 是一个框架,而不是另一种语言。

标签: php email cakephp cakephp-2.0


【解决方案1】:

听起来您已经在处理 zip 进度并且可以确定该过程何时完成,所以我会执行以下操作:

我建议您创建一个名为 EmailQueue 之类的新表和模型。然后我会创建一个 shell,例如 /app/Console/Command/EmailShell.php

/**
 * Shell to run background emails
 *
 * @property $EmailQueue
 */
class EmailShell extends AppShell {
    public $uses = array(
        'EmailQueue',
        'Model' // Name of model you are creating the zip for
    );

    public function main() {
        $this->out('You have hit the Email Shell.');
    }

    public function run_email_queue() {
        $emailQueueItem = $this->EmailQueue->find('first', array(
            'conditions' => array(
                'EmailQueue.status' => 0
            ),
            'order' => array(
                'EmailQueue.created ASC'
            )
        ));

        if(empty($emailQueueItem)) {
            $this->out('Email queue is empty.');
            return;
        }

        // Assuming you have a field for file status which is updated on zip completed
        // Alternatively, you could use a separate shell or cli to check
        switch($emailQueueItem['EmailQueue']['file_status']) {
            case "complete":
            case 1:
                $status = $this->send_email($emailQueueItem);
                break;

            default:
                $status = false;
                break;
        }

        if($status !== false) {
            // Update the status so that the email isn't sent later on
            $this->EmailQueue->id = $emailQueueItem['EmailQueue']['id'];
            $this->EmailQueue->save(array(
                'status' => 1
            ));
            $this->out(' ### Sending Email Successful');
        }
    }

    public function send_email($emailQueueItem = array()) {
        // Your model which does the zipping should have the email logic
        // I would have it return true or false.
        return $this->Model->originalEmailFunction($emailQueueItem['EmailQueue']['model_id']);
    }

}

上面是一个非常简化的 shell 示例,只需在你的模型中放置某种完成标志,或者在你的 shell 完成压缩后更新“EmailQueue”表,然后当你的 cron 命中这个 shell 时,它会发送电子邮件提供存在所述标志 - 如果您无法在控制器操作中处理它,您可能需要第二个 shell 来更新 zip 文件的标志。

【讨论】:

    【解决方案2】:

    您希望用户在文件上传时停留在原始页面上吗?如果是这样,您能否使用回调进行初始 Ajax 调用,并在该回调中执行您的电子邮件发送代码?

    或者,您可以有效地将其排队(也许只是通过在数据库的“电子邮件”表中创建一条记录)而不是立即发送电子邮件,并通过查看准备好发送的电子邮件进行 cron 作业检查查看上传的文件是否已完成压缩?

    【讨论】:

      【解决方案3】:

      出于流畅的响应时间的原因,我会使用现成的排队解决方案,例如:

      https://github.com/MSeven/cakephp_queue#readme
      

      【讨论】:

        猜你喜欢
        • 2017-09-30
        • 1970-01-01
        • 1970-01-01
        • 2011-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多