【问题标题】:How to override Monolog core handler?如何覆盖 Monolog 核心处理程序?
【发布时间】:2015-02-20 17:11:27
【问题描述】:

在 symfony 2.5.9 中,我尝试覆盖 Monolog 的 SwiftMailerHandler

class MySwiftMailerHandler extends SwiftMailerHandler
{
    public function __construct(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, $bubble = true)
    {
         $message->setSubject('Lorem ipsum : ' . $message->getSubject()) ;
         parent::__construct($mailer, $message, $level, $bubble);
    }
}

有服务

<service id="my_custom_handler" class="XXXX\Monolog\Handler\MySwiftMailerHandler">
    <tag name="monolog.handler.swift"/> <!-- which tag to use ? -->
</service>

和配置

monolog:
    handlers:
        mail:
            type:         fingers_crossed
            action_level: critical
            handler:      custom #before buffered
        custom:
            type: service
            id: my_custom_handler
        #buffered:
        #    type:    buffer
        #    handler: swift
        swift:
            type:       swift_mailer
            from_email: %monolog_from_email%
            to_email:   %monolog_to_email%
            subject:    'Error'
            level:      critical

但我的处理程序有以下错误:“__construct() 必须是 Swift_Mailer 的实例,没有给出...”

如何创建我的新处理程序服务?糟糕的配置独白?使用哪个标签?怎么做 ? 谢谢!

【问题讨论】:

  • 当您声明您的服务时,您没有传递任何必需的依赖项。建议您检查核心代码是如何执行此操作的,并在文档中阅读有关依赖注入的更多信息。

标签: symfony monolog


【解决方案1】:

这很棘手。所有各种处理程序类都被定义为monolog.xmlMonologBundle 内的参数。 (MonologExtension 似乎在一个大的 switch 语句中实例化和配置这些。)

要覆盖SwiftMailerHandler,请像这样指定类参数

parameters: ... monolog.handler.swift_mailer.class: XXXX\Monolog\Handler\MySwiftMailerHandler

无需乱用服务、标签等。

我使用这种方法覆盖SwiftMailerHandler::buildMessage() 并动态更改电子邮件的主题。

【讨论】:

  • 这不适用于新版本的独白/捆绑 (3.0)
【解决方案2】:

您可以使用编译器通道更改类:

Symfony documentation:如果你想修改另一个包的服务定义,你可以使用编译器传递来改变服务的类或修改方法调用。

// src/Kernel.php
namespace App;

// ...
+ use App\Service\YourService;
+ use Symfony\Component\DependencyInjection\ContainerBuilder;
+ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;

class Kernel extends BaseKernel implements CompilerPassInterface
{
+     public function process(ContainerBuilder $container)
+     {
+         $definition = $container->findDefinition('monolog.handler.swift');
+         $definition->setClass(YourService::class);
+     }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多