2017-01-16 2 views
0

Я настроил swiftmailer для отправки сообщений электронной почты с использованием типа файла. вот моя конфигурация swiftmailerSymfony - запустить консольную команду на kernel.terminate

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. 

Моя проблема, я не могу использовать кронтаб, потому что хрон может быть сконфигурирован с минимумом 1-минутного интервала, который я не могу себе позволить. Я хочу использовать фоновый процесс с немедленным выполнением после того, как ответ будет отправлен обратно в браузер, что минимизирует выполнение катушек до минимума.

Я попытался решить эту проблему, создав класс слушателя событий и слушать kernel.terminate, и выполнить команду, используя shell_exec или exec функцию, вот код для справки.

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

Что означает «это не работает»? – COil

+0

Он не отправляет электронное письмо, тогда как if echo '$ command' и копирует его в терминал, он работает. Я вижу, что даже если он выполняется, файлы спула не обрабатываются, обычно файлы спула удаляются, если они обрабатываются, а в моем случае они не удаляются. –

+0

Что такое вывод 'shell_exec ($ command);', может быть правильной проблемой? – COil

ответ

1

Пожалуйста, используйте тип катушки памяти о быстрой почтовой программе, это именно то, что вы хотите

При использовании подкачки для хранения сообщений электронной почты в память, они будет отправлен прямо перед завершением ядра. Это означает, что электронное письмо отправляется только в том случае, если весь запрос был выполнен без каких-либо необработанных исключений или любых ошибок. Чтобы настроить swiftmailer с опцией памяти, используйте следующую конфигурацию:

+0

Если вы внимательно прочитаете, он говорит, что он запускается непосредственно перед завершением ядра, это не значит, что он работает в фоновом режиме, он просто говорит, что он выполняется последним, я пробовал это и, к сожалению, это не соответствует мое требование :-) –

+0

до того, как ядро ​​завершилось = kernel.terminate event = после того, как ответ был отправлен клиенту, а 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); 
    } 
} 
Смежные вопросы