Php 我怎样才能在Symfony收集所有独白记录者?
我有一个创建不同对象的工厂类,并且为每种类型的对象定义了许多记录器。 我想在我的工厂里收集所有的伐木工人。在此之前,我只是在工厂构造函数中使用ContainerInterface,但由于Symfony 5.1容器自动连接不受欢迎。 现在我找不到办法收集伐木工人。我试着用Php 我怎样才能在Symfony收集所有独白记录者?,php,symfony,monolog,Php,Symfony,Monolog,我有一个创建不同对象的工厂类,并且为每种类型的对象定义了许多记录器。 我想在我的工厂里收集所有的伐木工人。在此之前,我只是在工厂构造函数中使用ContainerInterface,但由于Symfony 5.1容器自动连接不受欢迎。 现在我找不到办法收集伐木工人。我试着用 !tagged_iterator { tag: 'monolog.logger' } 还尝试为LoggerInterface设置一个标记,并为其获取一个标记的迭代器,但没有成功。我认为这是因为记录器不是真正的类。这可能有些过分
!tagged_iterator { tag: 'monolog.logger' }
还尝试为LoggerInterface设置一个标记,并为其获取一个标记的迭代器,但没有成功。我认为这是因为记录器不是真正的类。这可能有些过分,但正如您所说,记录器服务有点不寻常。似乎它们应该被LoggerInterface标记或可标记,但我运行了一些测试,无法使其工作。以下是一种暴力方法,它依赖于ID为monolog.logger.name的记录器服务:
# Start with a service locator class
namespace App\Service;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ServiceLocator;
class LoggerLocator extends ServiceLocator
{
// Just to specify the return type to keep IDEs happy
public function get($id) : LoggerInterface
{
return parent::get($id);
}
}
...
# now make the kernel into a compiler pass
# src/Kernel.php
class Kernel extends BaseKernel implements CompilerPassInterface
...
public function process(ContainerBuilder $container)
{
$loggerServices = [];
foreach($container->getServiceIds() as $id) {
if (!strncmp($id,'monolog.logger.',15)) {
//echo 'Logger ' . $id . "\n";
$loggerServices[$id] = new Reference($id);
}
}
$loggerLocator = $container->getDefinition(LoggerLocator::class);
$loggerLocator->setArguments([$loggerServices]);
}
# and now we can inject the locator where it is needed
class SomeController {
public function index(Request $request, LoggerLocator $loggerLocator)
{
dump($loggerLocator);
$logger = $loggerLocator->get('monolog.logger.' . $name);
似乎只有通过配置才能做到这一点,但我想传递过程非常简单。实际上,将ContainerInterface别名添加到services.yaml并继续使用现有代码非常简单。但我理解重构的愿望。如果您事先知道实际的服务ID,那么我认为服务定位器可以做到这一点?@Cerad,我读过一篇文章,但还不明白它如何帮助我。请解释一下您的建议好吗?在您当前的代码中,您是否有几行$container->get('logger1')代码。在我的代码中,我们有一个协议,即配置中的记录器与工厂对象具有相同的名称,所以我只使用
$container->get('monog.logger')。strtolower($name))
MonogBundle将在中创建基于通道的记录器别名,而不是将其作为常规配置的一部分。因此,它们可能还不可用。您可以在自定义编译器类中收集它们,该类在Monolog中的编译器类之后运行。据我所知,您不必手动排定优先级,但请参见