1

我想知道如何编写仅在kernel.terminate.

例如,当我打电话时:

$message = (new \Swift_Message('A new book has been added'))
            ->setFrom('system@example.com')
            ->setTo('contact@les-tilleuls.coop')
            ->setBody(sprintf('The book #%d has been added.', $book->getId()));
$this->mailer->send($message);

我知道内核将向客户端发送响应,并且仅在发送电子邮件之后。

我有很多可以调用的服务,kernel.terminate但我不知道如何编写它们以便仅在该事件中调用。

现在,我正在订阅者中编写编写代码:

public static function getSubscribedEvents()
    {
        return [
            KernelEvents::TERMINATE => [['doHeavyStuff', EventPriorities::POST_RESPOND]]
            ];
    }

但是以这种方式工作意味着我必须只处理请求和响应,并且我不想依赖响应。

if($method===Request::METHOD_PUT && isset($response['@type']) && $response['@type']==='Partner'){
 $this->notificationManager->sendNotificationAboutCart($response['partner']['id'],
                                                       $response['partner']['name']);
}

我不知道是否清楚,但是notificationManager在我的代码中调用我想要的任何地方并且该经理只在kernel.terminate.

4

1 回答 1

1

一个简单、幼稚的实现。

您的服务的send()方法实际上并没有发送任何内容,只是在时机成熟时添加另一个要发送的消息。

class ShinyService {
    private $messages = [];

    public function send($message) {
        $this->messages[] = $message;
    }

    public function processMessages()
    {
        foreach ($this->messages as $message) {
            // do the actual work, e.g. sending the message
        }
    }
}

然后是一个依赖于该服务的订阅者,因此它被注入到订阅者实例中:

class ShinySubscriber implements EventSubscriberInterface
{

    private $service;

    public function __construct(ShinyService $service) {
        $this->service = $service;
    }

    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::TERMINATE => [
                ['processMessages', 10]
            ],
        ];
    }

    public function processMessages(TerminateEvent $event)
    {
        $this->service->processMessages();
    }
}

这样你就可以在任何ShinyService地方注入,在任何时候调用ShinyService::send(),并且消息只会在KernelEvents::TERMINATE.

请记住,如果您使用的是 PHP-FPM,则此事件仅在发送响应后运行。从文档

在内部,HttpKernel 使用了 fastcgi_finish_request PHP 函数。这意味着目前只有 PHP FPM 服务器 API 能够向客户端发送响应,而服务器的 PHP 进程仍然执行一些任务。对于所有其他服务器 API,仍会执行 kernel.terminate 的侦听器,但在它们全部完成之前不会将响应发送到客户端。

于 2019-11-17T17:23:29.380 回答