Это не так просто, как кажется. Процессор либо зарегистрирован в регистраторе или через обработчик.
Если процессор зарегистрирован в регистраторе, невозможно узнать, через какой обработчик прошел процессор, так как все обработчики выполняются после выполнения всех процессоров. Если вы регистрируете процессор на обработчике, вы всегда знаете, какой обработчик выполняется, но регистрировать процессор для каждого обработчика вручную довольно обременительно.
Чтобы решить эту проблему, вы можете добавить CompilerPass, который выполняет ручную работу. для тебя.
Предположим, у нас есть этот процессор
class HandlerProcessor
{
/**
* @var string
*/
private $handlerName;
public function __construct($handlerName)
{
$this->handlerName = $handlerName;
}
public function processRecord(array $record)
{
$record['extra']['handler_name'] = $this->handlerName;
return $record;
}
}
С помощью этого процессора вы можете затем создать проход компилятора, который создает все определения для различных созданных монологов обработчиков.
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
class HandlerProcessorPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->hasParameter('monolog.handlers_to_channels')) {
return;
}
foreach ($container->getParameter('monolog.handlers_to_channels') as $handlerId => $channels) {
$definition = new Definition(HandlerProcessor::class);
$handlerDefinition = $container->getDefinition($handlerId);
$handlerName = $handlerDefinition->getClass();
$definition->addArgument($handlerName);
$handlerProcessorId = 'handler_processor.' . $handlerId;
$container->setDefinition($handlerProcessorId, $definition);
$handlerDefinition->addMethodCall('pushProcessor', array(new Reference($handlerProcessorId)));
}
}
}
Поскольку проходы компилятора могут быть довольно запутанными, если вы никогда не использовали их раньше, давайте построчно:
if (!$container->hasParameter('monolog.handlers_to_channels')) {
return;
}
Это проверяет, зарегистрирован ли пакет monolog. Параметр monolog.handlers_to_channels
добавляется в контейнер в MonologExtension< /а>. Сам параметр содержит массив, где ключ — это имя идентификатора обработчика, а значение — массив со всеми каналами, на которых зарегистрирован этот обработчик (или нуль, если этот обработчик действителен для всех каналов).
foreach ($container->getParameter('monolog.handlers_to_channels') as $handlerId => $channels) {
$definition = new Definition(HandlerProcessor::class);
$handlerDefinition = $container->getDefinition($handlerId);
Здесь мы создаем новое определение нашего HandlerProcessor
и получаем определение текущего обрабатываемого обработчика.
$handlerName = $handlerDefinition->getClass();
$definition->addArgument($handlerName);
Это позволит получить имя класса обработчика (например, Monolog\Handler\SlackHandler) и добавляет его в качестве аргумента конструктора в HandlerProcessor
$handlerProcessorId = 'handler_processor.' . $handlerId;
$container->setDefinition($handlerProcessorId, $definition);
$handlerDefinition->addMethodCall('pushProcessor', array(new Reference($handlerProcessorId)));
И последнее, но не менее важное: мы создаем новый идентификатор для определения процессора, которое мы только что создали в начале цикла foreach, и добавляем его с вызовом метода pushProcessor
в наш только что созданный процессор.
Теперь, когда все настроено, вы должны зарегистрировать этот проход компилятора в своем контейнере. Я предполагаю, что вы используете symfony 2.x, так что вы должны сделать это в своем AppBundle
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
$container->addCompilerPass(new HandlerProcessorPass());
}
}
Вот несколько дополнительных ссылок, которые могут быть полезны:
person
Martin Parsiegla
schedule
29.05.2018