2017-01-16 3 views
0

파일 유형을 사용하여 전자 메일을 스풀링하도록 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" 

내가 어떤 이메일이 완벽하게 스풀을 보내 내 swiftmailer의 설정

입니다. 그 후 이메일을 보내려면 다음 명령을 실행하십시오. 심포니 documentation

내 문제가 크론이 내가 감당할 수없는 1 분 간격의 최소 구성 할 수 있기 때문에, 내가 crontab을 사용할 수 없습니다입니다
the console command should be triggered by a cron job or scheduled task and run at a regular interval. 

에 따르면

bin/console swiftmailer:spool:send --env=dev 

. 응답이 브라우저로 다시 전송 된 후 즉각적인 실행으로 백그라운드 프로세스를 사용하여 최소의 스풀 실행을 최소화하고자합니다.

이벤트 리스너 클래스를 만들고 kernel.terminate을 청취하여이 문제를 해결하려고 시도했으며 shell_exec 또는 exec 함수를 사용하여 명령을 실행했습니다. 여기에 참조 용 코드가 있습니다.

app.kernel.terminate.listener: 
     arguments: ["@kernel"] 
     class: AppBundle\EventListener\KernelTerminateListener 
     tags: 
      - { name: kernel.event_listener, event: kernel.terminate } 

여기 내의 EventListener 클래스

내가 여기에 노력하고하는 것은 kernel.terminate 이벤트에 bin/console swiftmailer:spool:send --env=dev를 실행하는 것입니다
<?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); 
    } 
} 

, 불행하게도이 작동하지 않습니다,이 문제가 감사에 접근하는 방법에 대한 힌트입니다.

감사합니다.

+0

이것은 '작동하지 않음'을 의미합니까? – COil

+0

전자 메일을 발송하지 않는 반면,'$ command'를 echo하고 복사하여 터미널에 붙여 넣으면 작동합니다. 나는 그것이 실행 되더라도 스풀 파일은 처리되지 않는다는 것을 알 수있다. 보통 스풀 파일은 처리되면 삭제되고, 내 경우에는 삭제되지 않는다. –

+0

'shell_exec ($ command);'의 결과는 옳은 문제일까요? – COil

답변

1

, 당신이 메모리에 이메일을 저장하는 스풀링 사용할 때

을 원하는 정확히 수행, 빠른 우편물의 메모리 스풀 형식을 사용하십시오 그들이 커널이 종료되기 바로 전에 보내질 것입니다. 처리되지 않은 예외 또는 오류없이 전체 요청이 실행 된 경우에만 전자 메일이 전송됨을 의미합니다. 메모리 옵션을 사용하여 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); 
    } 
}