我已使用文件类型将swiftmailer配置为假脱机电子邮件。这是我的swiftmailer配置
swiftmailer:
transport: "%mailer_transport%"
host: "%mailer_host%"
username: "%mailer_user%"
password: "%mailer_password%"
spool:
type: file
path: "%kernel.root_dir%/../var/spool"
当我发送任何电子邮件时,它完全是假脱机。之后我运行以下命令发送电子邮件。
bin/console swiftmailer:spool:send --env=dev
根据Symfony documentation
the console command should be triggered by a cron job or scheduled task and run at a regular interval.
我的问题是,我不能使用crontab,因为cron可以配置至少1分钟的间隔,这是我买不起的。我希望在将响应发送回浏览器后立即执行后台进程,从而最大限度地减少假脱机的执行。
我尝试通过创建事件侦听器类并侦听kernel.terminate
来解决此问题,并使用shell_exec
或exec
函数执行命令,以下是参考代码。< / p>
app.kernel.terminate.listener:
arguments: ["@kernel"]
class: AppBundle\EventListener\KernelTerminateListener
tags:
- { name: kernel.event_listener, event: kernel.terminate }
这是我的EventListener类
<?php
namespace AppBundle\EventListener;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Cocur\BackgroundProcess\BackgroundProcess;
class KernelTerminateListener
{
protected $kernel;
protected $console;
public function __construct($kernel)
{
$this->kernel = $kernel;
$this->console = $this->kernel->getRootDir().'/../bin/console ';
}
public function onKernelTerminate(PostResponseEvent $event)
{
$command = $this->console.'swiftmailer:spool:send --env='.$this->kernel->getEnvironment();
shell_exec($command);
}
}
我在这里尝试的是在bin/console swiftmailer:spool:send --env=dev
事件上运行kernel.terminate
,遗憾的是这不起作用,任何关于如何处理此问题的提示都表示赞赏。
谢谢。
答案 0 :(得分:1)
请使用swift邮件程序的内存卷轴类型,它完全符合您的要求
当您使用假脱机将电子邮件存储到内存时,它们将在内核终止之前发送。 这意味着只有在整个请求执行时才会发送电子邮件,而不会发生任何未处理的异常或任何错误。要使用memory选项配置swiftmailer,请使用以下配置:
答案 1 :(得分:0)
不使用shel_exec而是使用进程组件,这将创建一个新进程,并在发送响应后执行命令。 shel_exec或exec将在相同的进程下执行,迫使内核等待完成请求(因为一旦父进程被终止,子进程也终止)。进程组件将创建一个新进程,在该命令下将执行。
use Symfony\Component\Process\Process;
....
....
....
public function onKernelTerminate(PostResponseEvent $event)
{
$command = $this->console.'swiftmailer:spool:send --env=.'$this->kernel->getEnvironment().'> output.log 2> out.log &';
$process = new Process($command);
$process->run();
}
答案 2 :(得分:-1)
也许这是PHP的一个问题,我使用MAMP和OSX预装了PHP,基本上,我安装了两个php版本,并且出于某种原因,当我给出正确的PHP路径时,它工作,这是我的更新了我重命名为MailerSpoolListener的侦听器类
<?php
namespace AppBundle\EventListener;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Cocur\BackgroundProcess\BackgroundProcess;
class MailerSpoolListener
{
protected $kernel;
protected $php;
protected $console;
protected $env;
protected $command;
protected $muteOutput;
public function __construct($kernel)
{
$this->kernel = $kernel;
$this->php = PHP_BINDIR.'/php';
$this->command = 'swiftmailer:spool:send';
$this->console = $this->kernel->getRootDir().'/../bin/console';
$this->env = $this->kernel->getEnvironment();
$this->muteOutput = '> /dev/null 2>/dev/null &';
}
public function onKernelTerminate(PostResponseEvent $event)
{
$command = $this->php.' '.$this->console.' '.$this->command.' --env='.$this->env.' '.$this->muteOutput;
$process = shell_exec($command);
}
}