【问题标题】:How to unlink files after they have been attached and sent? (When using Mail::queue)附加和发送后如何取消链接文件? (使用 Mail::queue 时)
【发布时间】:2014-05-13 17:04:57
【问题描述】:

我从立即发送邮件切换到将它们添加到队列中,这是我的代码,$attachments 是一个临时路径数组,我已经注释掉了我尝试过的内容,这会引发关于文件的错误现存的。

Mail::queue($view, $data, function(\Illuminate\Mail\Message $message) use($mail,$attachments){
    foreach($mail->getRecipients() as $recipient){
        $message->to($recipient);
    }
    $message->subject($mail->getSubject());
    foreach($attachments as $attachment){
        $message->attach($attachment);
        //this deletes the attachment before being sent
        //unlink($attachment);
    }
});
/* This code only works when using Mail::send() instead of Mail:queue()
foreach($attachments as $attachment){
    unlink($attachment);
}
*/

基本上我想在邮件发送后清理并删除我的临时附件。我猜这不适用于开箱即用的 laravel 邮件解决方案。如何触发代码post-queue-mail-sent

【问题讨论】:

    标签: php laravel-4 swiftmailer


    【解决方案1】:

    稍微扩展 Deric Lima 的答案,您不一定需要为此创建一个新的 Job 类。您也可以使用 Mailable 对象来做到这一点。只需覆盖send 方法即可。

    /**
     * @param MailerContract $mailer
     */
    public function send(MailerContract $mailer)
    {
        parent::send($mailer);
    
        //$this->clearAttachments is something you can defined in your constructor,
        //making it the responsibility of whatever is applying the attachment
        //to know whether it needs to remain in tact after the email is transmitted.
        if ($this->clearAttachments) {
            foreach ($this->attachments as $attachment) {
                if (\File::exists($attachment['file'])) {
                    \File::delete($attachment['file']);
                }
            }
        }
    }
    

    就个人而言,我会创建一个所有其他 Mailable 类扩展的 BaseMailable 类,而不是直接使用 Illuminate\Mail\Mailable。从此你就不用担心了。

    【讨论】:

      【解决方案2】:

      您必须等到队列处理完毕后才能删除文件。

      不知道队列的实现细节很难回答你的问题,但是如果你的队列在脚本结束之前被处理,你可以使用 register_shutdown_function http://www.php.net/manual/en/function.register-shutdown-function.php 运行清除文件的清理功能

      register_shutdown_function(function() use (filename){
          if (file_exists($filename)) {
              unlink($filename);
          }
      })
      

      【讨论】:

        【解决方案3】:

        我遇到了类似的问题,我使用Laravel Jobs 解决了。基本上,您可以创建一个 Job 类来发送电子邮件:

        class MailJob extends Job implements SelfHandling, ShouldQueue
        {
          use InteractsWithQueue, SerializesModels;
        
          public function handle()
          {
            Mail::send($view, $data, function (\Illuminate\Mail\Message $message) use ($mail, $attachments) {
                foreach ($mail->getRecipients() as $recipient) {
                    $message->to($recipient);
                }
                $message->subject($mail->getSubject());
                foreach ($attachments as $attachment) {
                    $message->attach($attachment);
                    unlink($attachment);
                }
            });
            foreach ($attachments as $attachment) {
                unlink($attachment);
            }
        }
        

        }

        然后你只需在控制器中调度你想要发送电子邮件的作业:

        $this->dispatch(new MailJob());
        

        P.S:作业在后台异步运行,所以我使用 Mail::send 而不是 Mail::queue。

        【讨论】:

          猜你喜欢
          • 2013-12-04
          • 2014-10-03
          • 2017-08-08
          • 2013-04-13
          相关资源
          最近更新 更多