If you would like to use logging functionality in Symfony2, you should access logger service via container.
For example in controller, you can easily access container and access logger service.
Well, that's it. However, this is big however for me, what should I do when accessing logger not from controller class?
Of course you can pass container or logger service itself to the class in service.yml
The following is my solution.
First, create MyLogger class.
In this example, the bundle class is under Example\LoggingExapleBundle.
For example in controller, you can easily access container and access logger service.
$logger = $this->get('logger'); $logger->info('I just got the logger'); $logger->error('An error occurred');
Well, that's it. However, this is big however for me, what should I do when accessing logger not from controller class?
Of course you can pass container or logger service itself to the class in service.yml
service_use_logger: class: LoggingExample\Service\ServiceUsingLogger arguments: - @logger
A bit pain everytime we should passing logger to the service class if you would like to use logger.
For Java or .Net, I have never seen general logging functionality is provided from dependency injection container.
For Almost all logging library, logger can be accessible as static - for example log4j.
The following is my solution.
First, create MyLogger class.
<?php namespace Example\LoggingExampleBundle\Library; class MyLogger { private $logger; public static function init(LoggerInterface $logger) { self::$logger = $logger; } public static function getLogger() { return self::$logger; } }And in your Bundle class, override boot method and inject logger service to MyLogger.
In this example, the bundle class is under Example\LoggingExapleBundle.
<?php namespace Example\LoggingExampleBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; use Example\LoggingExampleBundle\Library\MyLogger; class LoggingExampleBundle extends Bundle { public function boot() { parent::boot(); MyLogger::init($this->container->get('logger')); } }Ok, now you can call logging functionality everwhere by static manner.
MyLogger::getLogger()->error("We did it!");
This technique can be applied if you would like to make the services be accessible by static manner.
But this technique breaks concept of Symfony2 dependency injection, so you should not use this technique often and use very carefully... I think.
コメント
however you can use JMS/DiExtraBundle where injecting a service is as easy as one short annotation (@Inject)
IMO services should always be loaded on a need-to-use basis, otherwise sooner or later you'll end up haveing performance issues
class MyLogger
{
private $logger;
public static function getLogger()
{
global $kernel;
if (!self::$logger)
{
self::$logger = $kernel->getContainer('logger');
}
return self::$logger;
}
}
Thank you for your comment. I didn't know JMS/DiExtraBundle! That's what I was looking for.
Also I completely agree that services should be loaded on needed-to-use basis. Do you know if we define bunch of services in services.yml, it harms the performance?
I think in Java framework like spring etc, the classes defined in container will be loaded on memory once when the application is launched, and after that it will simply run on memory for normal Java application runnning.
I'm not sure how Symfony2 DI container works.
(maybe I should read the official Symfony2 document.)
Oh thank you very much for your comment!
I have a question for your code.
Could you tell me where should I assign value to $kernel? Do you think inside Bundle::boot method is the proper place?
thanks!