根据您在Github上的示例,您在构造函数中注入了记录器接口,其默认值为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
}
}
表示某些东西有Logger,您可以实施Psr\Log\LoggerAwareInterface
和Psr\Log\LoggerAwareTrait
。
重建示例代码,它看起来像这样
<?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
}
}
这很好并且工作但是如果我会这样做
<?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
}
}
它最终会出现must be an instance of Psr\Log\LoggerInterface, null given
错误,因为接口中的方法声明没有NULL默认值。当然,可以通过使用if或NullLogger
来防止此错误,但这非常奇怪。
Beeing能够在构造函数中传递可选的Logger实例会让我觉得我可以稍后通过将Logger设置为NULL值来更改实例。当然这是一个示例代码,但让我们看一下问题
public function __construct(LoggerInterface $logger = null);
public function setLogger(LoggerInterface $logger);
所以基本上我可以将NULL引用传递给构造函数但是我不可能调用setter因为不允许NULL。如果Psr\Log\LoggerAwareInterface
看起来像这样
<?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);
}
那么请告诉我这个决定的背景?
答案 0 :(得分:2)
我认为你在这里混合了许多问题。
示例用法https://github.com/php-fig/log#usage显示了如何在应用程序中使用psr/log
实现。它也是正确的。
所以接下来的问题是LoggerAwareInterface
对LoggerAwareTrait和setLogger
方法的使用
public function __construct(LoggerInterface $logger = null)
{
$this->setLogger($logger);
}
如果构造函数接受null,则不应调用setLogger
方法。 setLogger
方法只能接受LoggerInterface
,并且不会意外地将记录器对象设置为null。
让我们说签名是setLogger($logger = null)
。现在,如果您在下面的示例中调用setLogger()
,则可以看到记录器将重置为null。
$logger = new SomePSR-3Logger();
$foo = new Foo($logger);
$foo->setLogger();
如果您想要实施PSR-3记录器,您应该考虑阅读:https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
希望有所帮助。
谢谢。