问题
I want to have Psr\Log\LoggerInterface
public in symfony to be able to get it directly from the container with $container->get('Psr\Log\LoggerInterface')
.
I tried the following services.yaml
:
_defaults:
public: true
Psr\Log\LoggerInterface:
public: true
Psr\Log\LoggerInterface:
alias: 'logger'
public: true
Psr\Log\LoggerInterface:
alias: 'monolog.logger'
public: true
I can not get a clue why it is so hard to rewrite a service.
回答1:
As previously noted, directly accessing services from the container is discouraged. But I was a bit curious to see how to make a private service public. I tried what was listed in the question and confirmed it did not work.
This may not be the simplest approach but a compiler pass will do the trick:
# src/Kernel.php
# Make the kernel a compiler pass
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
class Kernel extends BaseKernel implements CompilerPassInterface
...
public function process(ContainerBuilder $container)
{
$logger = $container->getAlias(LoggerInterface::class);
$logger->setPublic(true);
}
# And that should do the trick, you can confirm with
bin/console debug:container Psr\Log\LoggerInterface
Be aware that only services which have the complete container injected will be able to take advantage of this. Controllers which extend from AbstractController only have access to a small number of services.
Take a look at Service Subscribers if you need the logger in your controller or if you just want a "better" way of doing this.
回答2:
Using $container->get() is a bad practise. It violates many good software design principles.
You should use constructor injection instead.
class Foo
{
protected $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
}
来源:https://stackoverflow.com/questions/55042137/how-to-make-loggerinterface-service-public-in-symfony-4