2017-01-16 111 views
0

我已經配置swiftmailer使用文件類型來後臺打印郵件。這裏是我的swiftmailer配置Symfony - 在kernel.terminate上運行console命令

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_execexec功能的命令,這裏是參考代碼。

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

什麼我想在這裏對kernel.terminate事件運行bin/console swiftmailer:spool:send --env=dev,不幸的是這不工作,對如何處理這個問題是能夠理解的任何提示。

謝謝。

+0

這是什麼意思'這不起作用'? – COil

+0

它不派遣電子郵件,而如果我回顯'$命令'並複製粘貼到終端,它的工作原理。我可以看到,即使它被執行,假脫機文件也不會被處理,通常假脫機文件被處理後會被刪除,而在我的情況下,它不會被刪除。 –

+0

'shell_exec($ command);'的輸出是什麼,',可能是一個正確的問題? – COil

回答

1

請使用SWIFT郵包的記憶滑閥式,這不正是你想要什麼

當您使用假脫機存儲電子郵件,存儲,他們將在內核終止之前發送。 這意味着如果整個請求得到執行沒有任何未處理的異常或任何錯誤,只發送電子郵件。要使用內存選項配置swiftmailer,請使用以下配置:

+0

如果你仔細閱讀,它說,它在內核終止之前就被執行了,這並不意味着它在後臺運行,它只是說它是最後一次運行,我已經嘗試過,很遺憾,這不符合我的要求:-) –

+0

內核終止之前= kernel.terminate事件=響應發送到客戶端和fastcgi_finish_request()被稱爲 –

+0

你是對的,我找到了多個參考,解釋你想說什麼,不幸的是它沒有爲我工作,也許是因爲這裏解釋的原因http://stackoverflow.com/questions/23719821/response-returned-only-after-kernel-terminate-event謝謝你指點我正確的方向。 +1 –

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