According to your sample on Github you inject the logger interface in the constructor with default value of NULL.
<?php
use Psr\Log\LoggerInterface;
class Foo
{
private $logger;
public function __construct(LoggerInterface $logger = null)
{
$this->logger = $logger;
}
public function doSomething()
{
if ($this->logger) {
$this->logger->info('Doing work');
}
// do something useful
}
}
Expressing that something has a Logger you can implement Psr\Log\LoggerAwareInterface
and the Psr\Log\LoggerAwareTrait
.
Rebuilding the sample code it would look something like this
<?php
use Psr\Log\LoggerInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
class Foo implements LoggerAwareInterface
{
use LoggerAwareTrait;
public function __construct(LoggerInterface $logger = null)
{
$this->logger = $logger;
}
public function doSomething()
{
if ($this->logger) {
$this->logger->info('Doing work');
}
// do something useful
}
}
Thats fine and working but if i would do this
<?php
use Psr\Log\LoggerInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
class Foo implements LoggerAwareInterface
{
use LoggerAwareTrait;
public function __construct(LoggerInterface $logger = null)
{
$this->setLogger( $logger );
}
public function doSomething()
{
if ($this->logger) {
$this->logger->info('Doing work');
}
// do something useful
}
}
it would end up in a must be an instance of Psr\Log\LoggerInterface, null given
error because there is no NULL default value on the method declaration in the interface. Of course this error can be prevented by guarding with an if or passing a NullLogger
but this is very weird.
Beeing able to pass an optional Logger instance in the constructor would make me think that i can alter the instance later by setting the Logger to a value of NULL. Of course this is a sample code but lets look at the problem
public function __construct(LoggerInterface $logger = null);
public function setLogger(LoggerInterface $logger);
So basically i can pass a NULL reference into the constructor but i would not be possible to call the setter because NULL is not allowed. It would have been much better if the Psr\Log\LoggerAwareInterface
would look like this
<?php
namespace Psr\Log;
/**
* Describes a logger-aware instance.
*/
interface LoggerAwareInterface
{
/**
* Sets a logger instance on the object.
*
* @param LoggerInterface $logger
*
* @return void
*/
public function setLogger(LoggerInterface $logger = null);
}
So please tell me the background to this decision ?
I think you are mixing many questions here.
The example usage https://github.com/php-fig/log#usage shows how you can use a
psr/log
implementation in your application. It does it correctly too.So the next question is about usage of LoggerAwareInterface and
setLogger
method via the LoggerAwareTraitIf your constructor is accepting null, you should not call the
setLogger
method. ThesetLogger
method can only acceptsLoggerInterface
and it doesn't accidentally need to set the logger object to null itself.Lets say the signature was as
setLogger($logger = null)
. Now if you callsetLogger()
as in example below you can see the logger will be reset to null.If you want to implement a PSR-3 logger you should consider reading : https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
Hope that helps.
Thank you.